comp.lang.ada
 help / color / mirror / Atom feed
From: "Ehud Lamm" <mslamm@mscc.huji.ac.il>
Subject: Re: When to use 'Class in a parameter list
Date: Tue, 24 Jul 2001 18:16:38 +0300
Date: 2001-07-24T18:16:38+03:00	[thread overview]
Message-ID: <9jk3lr$ki0$1@news.huji.ac.il> (raw)
In-Reply-To: 9jjqt0$o1s$1@nh.pace.co.uk


Marin David Condic <marin.condic.auntie.spam@pacemicro.com> wrote in message
news:9jjqt0$o1s$1@nh.pace.co.uk...
> "Ehud Lamm" <mslamm@mscc.huji.ac.il> wrote in message
> news:9ji5j7$hlu$1@news.huji.ac.il...
> > > type? I was under the impression that I would use 'Class if I wanted
to
> > make
> > > an operation that worked on anything derived from the class without
> > explicit
> > > conversion. (Possible to override it in a child class, AFAIK...)
> >
> >
> > You mean _impossible_ right?
> >
> Uhhhh Dunno... I seem to have a procedure at one level that takes an
> Object'Class parameter and I overrode it one level up with an identical
> procedure taking an Object_Child'Class. The compiler didn't complain and
the
> code appears to work. Maybe it shouldn't, but there you have it...
>

I didn't mean to imply that you can't write this kind of routine. Only that
the intuition is the reverse. But this is *not* overriding exactly, since
the inheritance relation is between Object and Object_Child and not between
the class-wide types. Again, the real isssue is dispatching, as explained in
the retional.
You may want to keep in mind that we are not just thinking about formal
parameters. The language has class-wide types, so you can have class-wide
value (usually an access Obj'class kind of thing). The important relations
are between these and dispatching, as shown in this table from the
Rationale:



     +----------+---------------------------------+
     |              |                  formal               |
     |   actual |        specific   |    class-wide |
     +----------+----------------+----------------+
     |              |                       |                    |
     | specific |  static binding|  class-wide op |
     |              |                      |                    |
     |----------+--------------   --+----------------|
     |             |                          |                  |
     |class-wide|   dispatching  | class-wide op  |
     |              |                         |                |
     +----------+---------------------------------+

                  Table 4-1: Kinds of Binding


An operand used to control dispatching is called a controlling operand. A
primitive operation may have several controlling operands; a primitive
function may also have a controlling result.

(Sorry if the mail software destroys the layout...)

>
> > Basically if you want overriding to be an option you use a primitive
> > operation. Notice that you have to think about the possible evolution of
> the
> > system, not about how things work the first time around.
> >
> Primitive operation? What do you mean? Like if I have a "procedure C (Obj
:
> in out Object);" as opposed to "procedure C (Obj : in out Object'Class);"?

Yes. Again let me quote the paragraph from the Rationale:

"With the increased importance of derived types for object oriented
programming in Ada 95, the notion of the operations closely related to a
type in this manner is generalized. The primitive operations of a type are
those that are implicitly provided for the type and, for types immediately
declared in a package specification, all subprograms with an operand or
result of the type declared anywhere in that package specification. The
domain is therefore extended to include the private part (but not the body).

Thus, in Ada 95, the derivable operations of Ada 83 have become "primitive
operations" and the restriction of these operations to the visible part of a
package has been eliminated. These changes support added capability:
primitive operations may be private and a type and its derivatives may be
declared in the same declarative region (this property is useful for
building related abstractions and was used in the package New_Alert_System
of Part One).

Primitive operations clarify the notion of an abstract data type for
purposes of object oriented programming (inheritance and polymorphism) and
genericity. They are distinguished from the other operations of a type in
the following ways

* Inheritance. Primitive operations are the derivable (inherited)
operations.
* Polymorphism. Primitive operations are dispatching operations on tagged
types.
* Genericity. Primitive operations are the ones available within generic
templates parameterized by a class. "

The key line here is the one about polymorphism.

>
>
> > The main question is not about the conversion, but whether calling the
> > routine requires run-time dispatching. (essentialy, the class-wide
routine
> > doesn't need dispatching). The Rationale has a couple of tables that
> nicely
> > show the dispatching/non-dispatching semantics of the various parameter
> > lists.

> Now you've got me thinking it should dispatch. Does it or does it not? I
> sort of conceptualized the 'Class operations (based on examples from a
> couple of books - which I badly need to re-read apparently! :-) as "This
> procedure should work on anything derived from this class because it only
> operates on the base-level components and generally should not be
something
> that is overriden". Whereas, the operations on some base type without the
> 'Class operation seemed to be saying to me "O.K. This operation works on
the
> base type, but you will probably be overriding it to provide additional
> capabilities when you derive a child type." Perhaps my conception of this
is
> inaccurate...
>

The way I explain it to my students is like this "from the 'outside' of the
class-wide routine there no dispatching" (i.e., no dispatching on call to
the class-wide routine), "from the 'inside' you can have dispathcing, by
calling the dispatching operations" (i.e, calls to primitive routine, made
inside the class-wide routine).
Notice that when you call a  routine that expect a specific type, from
inside a class-wide routine you are, in a sense, giving a class-wide
actual - and per the table above you may have dispatching.

Another way at looking at this, is to realize that the class-wide operation
behave the same for all type in the hierarchy, up to calls to dispatching
routines. The commonality is expressed by creating a class-wide routine; the
routine can be sensitive to the differences between the types in the
hierarchy by calling type specific (dispatching) routines.
Aside from the concept of "template function pattern", another common term
is "factoring out common behaviours" - this may give a better idea what's
this all about from a design POV.

Ehud Lamm





  parent reply	other threads:[~2001-07-24 15:16 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-07-23 20:27 When to use 'Class in a parameter list Marin David Condic
2001-07-23 21:39 ` Ehud Lamm
2001-07-24 12:49   ` Marin David Condic
2001-07-24 14:39     ` Dmitry A. Kazakov
2001-07-24 15:16     ` Ehud Lamm [this message]
2001-07-24 17:16       ` Marin David Condic
2001-07-23 22:55 ` Stephen Leake
2001-07-25 19:20   ` Deligation with Ada95 Hans-Olof Danielsson
2001-07-26  2:06     ` Lao Xiao Hai
2001-07-24  2:22 ` When to use 'Class in a parameter list Vincent Marciante
2001-07-24 12:52   ` Marin David Condic
2001-07-24 14:36     ` Ed Falis
2001-07-24 15:29       ` Ehud Lamm
2001-10-29 22:52 ` Matthew Heaney
replies disabled

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