comp.lang.ada
 help / color / mirror / Atom feed
* Package name qualifier on function?
@ 1998-02-06  0:00 Lane Wimberley
  1998-02-06  0:00 ` Matthew Heaney
  0 siblings, 1 reply; 2+ messages in thread
From: Lane Wimberley @ 1998-02-06  0:00 UTC (permalink / raw)



I am new to the world of Ada programming.  I have come across the
following and my Rational VADS compiler has no trouble with it.

-- code somebody else wrote...
-- Foo spec:
package Foo is
  type internalfoothing is private;
  function create return internalfoothing;
private
  type somethingelse;
  type somethingelseptr is access somethingelse;
  type internalfoothing is new somethingelseptr;
end Foo;

-- spec of different package that withs Foo package:
with Foo;
package Bar is 
  type FooThing is private;
private
  type FooThing is new Foo.internalfoothing;
end Bar;

-- body of different package 
package body Bar is

function create(param : someparamtype) returns FooThing is 
  newfoothing : FooThing;
begin
  newfoothing := create;  -- why is this OK?
  return newfoothing;
end create;

end Bar;

As the comment indicates, I can't figure out why the compiler
accepts the invocation of "create" without any package qualifier.
I would have expected to see "Foo.create"  Also, why do I get no
complaint about the fact that "create" returns an InternalFooThing
yet newfoothing is of type FooThing?

Any help MUCH appreciated!

-- 
Lane Wimberley
Microelectronics and Computer Technology Corporation
Austin, TX




^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Package name qualifier on function?
  1998-02-06  0:00 Package name qualifier on function? Lane Wimberley
@ 1998-02-06  0:00 ` Matthew Heaney
  0 siblings, 0 replies; 2+ messages in thread
From: Matthew Heaney @ 1998-02-06  0:00 UTC (permalink / raw)



In article <34DB9059.7E4E@mcc.com>, Lane Wimberley <lane@mcc.com> wrote:

>package Foo is
>  type internalfoothing is private;
>  function create return internalfoothing;
>private
>  type somethingelse;
>  type somethingelseptr is access somethingelse;
>  type internalfoothing is new somethingelseptr;
>end Foo;
>
>-- spec of different package that withs Foo package:
>with Foo;
>package Bar is 
>  type FooThing is private;
>private
>  type FooThing is new Foo.internalfoothing;
>end Bar;
>
>-- body of different package 
>package body Bar is
>
>function create(param : someparamtype) returns FooThing is 
>  newfoothing : FooThing;
>begin
>  newfoothing := create;  -- why is this OK?
>  return newfoothing;
>end create;
>
>end Bar;
>
>As the comment indicates, I can't figure out why the compiler
>accepts the invocation of "create" without any package qualifier.
>I would have expected to see "Foo.create"  Also, why do I get no
>complaint about the fact that "create" returns an InternalFooThing
>yet newfoothing is of type FooThing?

You must understand the concept of "type," and the concept of a "primitive
operation" of a type.

In any system, there are probably thousands of subprograms.  Some of these
subprograms have as a parameter an object of type T (say), and maybe some
others are functions that return an object of type T.

Among this subset of all the subprograms in the system, there's another
subset, the subset comprising the "primitive operations" of type T.  The
larger subset are all "operations" of type T, but not all of them are
"primitive" operations.

Let type T be declared in package P:

package P is

   type T is range 2 .. 5;

   procedure Op1 (O : T);

   function Op2 (I : Integer) return T;

end P;

with P;
package Q is

   procedure Op3 (O : P.T);

   function Op4 (F : Float) return P.T;

end Q;

There are 4 total subprograms - "operations" - that take T as a parameter
or return value.  Among this group of subprograms are 2 that are "primitive
operations of type T": Op1 and Op2.  The rule is that the subprograms that
take an argument of the type or return a value of the type, and are
declared in the same package as the type declaration itself, are "primitive
operations" of the type.  Operations Op3 and Op4 do take a parameter of
type T or return a value of type T, but these operations are not "primitive
operations" in the sense of Op1 and Op2.

The reason we make this distinction is that primitive operations of a type
- and only primitive operations - are inherited by a type that derives from
that type.  For example, let's derive a type from T:

with P;
package R is

   type NT is new P.T;

end R;

There are 2 "primitive operations" for type NT.  It's as if package R were

with P;
package R is

   type NT is new P.T;

   procedure Op1 (O : NT);

   function Op2 (I : Integer) return NT;

end R;

When NT derived from T, the primitive operations of T came along for the
ride.  We say that Op1 and Op2 are "implicitly declared" immediately after
the declaration of type NT. 

This makes sense when you consider what a "type" is.  A "type" is

1) a set a values

2) a set of operations

The type T comprises 

1) the integer values 2, 3, 4, 5

2) the "predefined" operations +, -, *, /, etc, and the "user-defined" (I
don't know if that's the exact technical term) operations Op1 and Op2.

When NT derives from type T, it (essentially) denotes the same values as T
and the same operations of T.

Many Ada programmers don't understand the subtlety of this.  When you say
"type T" programmers often think that it means the same thing as the
statement "type T is range 2 .. 5;".  Not quite.  The statement 

type T is range 2 .. 5;

is actually a "binding" operation, that binds a name, here "T", to a type,
comprising the values 2, 3, 4, 5, and the operations +,-, etc, Op1, and
Op2.

Ever here of the expression "The map is not the territory"?  Well the same
principle is at work here.  "T" is the *name* of a type, it is not the
type.  Nor is the statement the declares the type, the type.  The "type" is
the set of values and the set of operations.

Many programmers think that package P declares "a type and 2 subprograms"
but that's not quite right.  Package P declares a type. Period.  The type
comprises the values and operations, and a name is bound to that type.

When type Bar.Foothing derived from Foo.internalfoothing, it's as if the
declaration were

with Foo;
package Bar is 
  type FooThing is private;
private
  type FooThing is new Foo.internalfoothing;
  function create return foothing;
end Bar;

Because type FooThing derives from Internalfoothing, it inherits the
"primitive" operations of that type, here operation create.  And that's why
operation create is directly visible in the body of package Bar, because
it's a primitive operation of FooThing, implicitly declared immediately are
the derivation from internalfoothing.

This concept is import for object-oriented programming too.  During a
derivation, the tagged derived type inherits the primitive operations of
the parent tagged type.  The difference between your example and true
"object-oriented" programming is that in "object-oriented" programming you
can "extend" the type; that wasn't possible in Ada 83.

Some authors make the distinction between "inheritence" and "type
extension."  That's why you'll often hear Ada 95 described as adding "type
extension" to the language, because "inheritence (of operations)" was
already in the language.

A lot of people who denigrated Ada 83 because it was "merely" object-based
are sort of missing the boat, because Ada 83 already had a lot of powerful
features for creating abstractions.  The fact that it didn't have type
extension shouldn't have been such a big deal (it wasn't for me) because
type extension and polymorphism are only ADJUNCTS to data abstraction. 
It's direct support for data abstraction that's important, not inheritance
(type extension) and polymorphism.  To measure a language by its support
for inheritance and polymorphism, and ignore support for data abstraction,
is backwards thinking.

Hope that clears things up.

Matt




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1998-02-06  0:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-02-06  0:00 Package name qualifier on function? Lane Wimberley
1998-02-06  0:00 ` Matthew Heaney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox