From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,b74ec64483660e21 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-07-24 08:21:05 PST Path: archiver1.google.com!newsfeed.google.com!newsfeed.stanford.edu!bloom-beacon.mit.edu!nycmny1-snh1.gtei.net!chcgil2-snf1.gtei.net!news.gtei.net!news.huji.ac.il!not-for-mail From: "Ehud Lamm" Newsgroups: comp.lang.ada Subject: Re: When to use 'Class in a parameter list Date: Tue, 24 Jul 2001 18:16:38 +0300 Organization: The Hebrew University of Jerusalem Message-ID: <9jk3lr$ki0$1@news.huji.ac.il> References: <9ji1b3$4pi$1@nh.pace.co.uk> <9ji5j7$hlu$1@news.huji.ac.il> <9jjqt0$o1s$1@nh.pace.co.uk> NNTP-Posting-Host: di4-42.dialin.huji.ac.il X-Trace: news.huji.ac.il 995987964 21056 132.64.14.42 (24 Jul 2001 15:19:24 GMT) X-Complaints-To: abuse@news.huji.ac.il NNTP-Posting-Date: Tue, 24 Jul 2001 15:19:24 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.00.2014.211 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2014.211 Xref: archiver1.google.com comp.lang.ada:10521 Date: 2001-07-24T18:16:38+03:00 List-Id: Marin David Condic wrote in message news:9jjqt0$o1s$1@nh.pace.co.uk... > "Ehud Lamm" 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