comp.lang.ada
 help / color / mirror / Atom feed
From: bobduff@world.std.com (Robert A Duff)
Subject: Re: Choice of OO primitives in Ada95
Date: 1996/02/23
Date: 1996-02-23T00:00:00+00:00	[thread overview]
Message-ID: <Dn8wz9.Eqp@world.std.com> (raw)
In-Reply-To: Dn22M0.G0D@assip.csasyd.oz

In article <Dn22M0.G0D@assip.csasyd.oz>,
Don Harrison <donh@syd.csa.com.au> wrote:
>Robert A Duff writes:
>:No, they don't have to be in the same package (and as you say, probably
>:should not be).  Could you explain what you mean -- why do you think
>:that all of the above types have to be in the same package?
>
>I don't have an RM available but quoting you (25.1.96) on the subject of dispatching
>operations in response to Arcadio A. Sincero:
>
>> >As a matter of fact, the only indication that TPerson's Walk "belongs to
>> >it" is that TPerson's Walk has a TPerson parameter.
>
>> That, plus the fact that it's in the same package.
>
>So, if you want all of the operations to be dispatching (primitive), then the
>tagged types must also be in the same package.

Sorry, you misunderstood me.  In Ada, a procedure can only be
dispatching on *one* type.  It can have several parameters of that type,
and a result of that type (if it's a function).  But there is a run-time
check that all of those parameters have the same type tag.  Ada does not
have multi-dispatching, like CLOS does.  But neither to any of the
languages (such as Eiffel) that use the prefix notation.

Now a procedure that's dispatching on type T can have other parameters
of other types.  It does not need to be in the same package as those
other types.  Same thing in Eiffel -- the operation is inside one class,
and is dispatching (only) on that class, but can have parameters of some
other class.

So, typically, you put exactly one type in a package, and put its
primitive (dispatching) operations in that same package.  You can put
operations that don't dispatch on that type in some other package.

The one case where this doesn't work too well is when you have two types
that are defined in terms of each other (e.g. T1 contains a pointer to
T2, and T2 contains a pointer to T1).  When this happens, you are forced
to put both types in the same package, or use one of the slightly ugly
workarounds that have been discussed here recently.  I admit that is a
language design flaw.  But don't generalize that to say that all types
in your entire program have to get sucked into the same package!

>In the same thread, Jon S Anthony went on to say that non-dispatching operations
>using tagged types were those defined in different packages to those types:
>
>> Just to add one more bit (completely beating it to death...), it is also
>> legal to have a subprogram with operands of both types as long as it is
>> not in the package where the two types are declared.  Of course such a
>> subprogram is not primitive and will never dispatch (assuming it has no
>> other controlling operands).
>
>Dispatching or not dispatching depending on where an operation is defined is not
>what you would call consistent.

Heh?  I thought you were arguing in favor of the class-based languages,
which do exactly that.  In Eiffel, an operation is dispatching based on
which class it's in.

In CLOS, you can have dispatching operations that are declared whereever
you want.  That can lead to some rather disorganized code, but I suppose
it's necessary if you're going to have multi-methods.  Anyway, I think
it's best to gather the dispatching operations together with the type
(either inside it, as in Eiffel, or in the same package, as in Ada).

Note also that in Eiffel you can declare that a given operation cannot
be further overridden ("frozen", or something like that?).  That's a
very similar feature to what you complain about here -- in part, it is a
hint to the compiler that calling that function won't dispatch to
someplace else, and in part, it's a help in understanding the program,
because you can know exactly which function is being called.

>A couple of other gripes:
>
>1) Why should you have to specify that a type is 'tagged'? Can't the compiler work
>that out for itself? eg. by seeing whether the type is extended elsewhere. The
>developer is forced to worry about what should be an implementation issue.

No, the compiler cannot tell, because of separate compilation.  It can't
tell in the Eiffel case, either, for the same reason.  But in Eiffel,
everything's dispatching.  If you're willing to do extra work at link
time, then you can optimize away the tag field.  But not at compile
time.

Note that C++ has essentially the same thing -- the "virtual" keyword.
If there are no virtual functions in a class, then no tag field is
necessary.  In Ada, if there is no "tagged" keyword, then no tag field
is necessary.  (One difference between Ada and C++ is that in Ada you
cannot extend an untagged type with extra record components, whereas as
you *can* do that in C++ (i.e. you can extend a class that has no
virtual functions.  There was a big fight about that during the design
of Ada 9X.  I don't like the way it turned out).

So, you're pretty much correct that "tagged" is not a logical necessity.
It is, in fact, an efficiency hack.

>2) Similarly, why should the developer have to specify that an operation dispatches
>(classwide operations)? Presumably, you're aiming for quicker execution, but
>compilers could perform a certain degree of optimisation eg. If it knows the type
>is not extended anywhere, there is no need to dispatch. There would also be
>situations where the specific variant of an inherited type is known eg. following
>an explicit assignment from an entity of that type.

The reason for this is to avoid what is sometimes called the "fragile
base class" problem that occurs in many large OO programs.  If
*everything* is potentially dispatching, it's much harder to understand
the program.  Better to do something special if you want dispatching.

Another reason is of course upward compatibility.  Ada 83 subprograms
did not do dispatching, and of course you don't want all your Ada 83
programs to drastically change their behavior when compiled by an Ada 95
compiler.

I suppose quicker execution is part of the reason, but it's not the main
thing.

Another point about the design of Ada's OOP: It was essential that there
be little or no distributed overhead.  That is, if you don't use the
feature, your program should not be slowed down by the mere existence of
the feature.  And if you recompile an Ada 83 program with an Ada 95
compiler, it shouldn't get slower (assuming the Ada 95 compiler is as
high quality as the Ada 83 one).  If dispatching always happened, there
would be distributed overhead (both space and time), that could not be
eliminated without link-time optimizations.

- Bob




  parent reply	other threads:[~1996-02-23  0:00 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <DMqHqF.9F1.0.-s@inmet.camb.inmet.com>
     [not found] ` <DMu9yw.5ts@assip.csasyd.oz>
     [not found]   ` <4g2f8v$15lc@watnews1.watson.ibm.com>
1996-02-19  0:00     ` Choice of OO primitives in Ada95 Don Harrison
1996-02-19  0:00       ` Robert A Duff
1996-02-20  0:00         ` Don Harrison
1996-02-20  0:00           ` Jon S Anthony
1996-02-22  0:00             ` Real OO (was Choice of OO primitives in Ada95) Don Harrison
1996-02-22  0:00               ` Jon S Anthony
1996-02-22  0:00               ` Robert Dewar
1996-02-23  0:00                 ` Gene Ouye
1996-02-26  0:00                   ` James O'Connor
1996-02-26  0:00                     ` Gene Ouye
1996-02-24  0:00               ` Robert A Duff
1996-02-26  0:00                 ` Don Harrison
1996-02-26  0:00                 ` Matthew B. Kennel
1996-02-24  0:00               ` Valery Croizier
1996-02-26  0:00               ` So called Real OO (was blah blah blah...) Jon S Anthony
1996-02-20  0:00           ` Choice of OO primitives in Ada95 Ray Toal
1996-02-21  0:00             ` Don Harrison
1996-02-23  0:00               ` Robert A Duff
1996-02-22  0:00             ` Bernd Holzmueller
1996-02-23  0:00               ` Robert A Duff
1996-02-23  0:00           ` Robert A Duff [this message]
1996-02-19  0:00       ` Norman H. Cohen
1996-02-21  0:00       ` Robert I. Eachus
1996-02-21  0:00     ` John DiCamillo
1996-02-22  0:00       ` Don Harrison
1996-02-24  0:00         ` Robert A Duff
     [not found] <4fmrhk$7k3@erinews.ericsson.se>
1996-02-19  0:00 ` Richard A. O'Keefe
replies disabled

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