From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Date: 18 Aug 93 19:22:28 GMT From: cis.ohio-state.edu!math.ohio-state.edu!darwin.sura.net!source.asset.com!c ernosek@ucbvax.Berkeley.EDU (Gary J. Cernosek) Subject: Re: OO Preprocessor for Ada Message-ID: <1993Aug18.192228.40908@source.asset.com> List-Id: In article <15JUL199315464091@cl2.cl.uh.edu> RILEY@cl.uh.edu writes: >Thanks for the suggestions, but I still have a couple of questions: > >In article , stt@spock.camb.inmet.com (Tucker Taft) writes.. >>>>Here are some possible look and feel issues: >>>> >>>> 1) Prefix notation >>>> i.e. blah.operation(params) instead of operation(blah,params) >> >>However, this breaks down for binary operators. One nice >>feature of CLOS and Ada 9X, is that binary operators are handled >>symmetrically, without any need for non-inheritable "friends." This is indeed the benefit of having the "target object" for an operation be passed as an explicit parameter to an operation. But in the cases where an operation is performed on a single object (i.e., unary operations), some may feel the syntax that John Riley is searching for would make Ada "more object-oriented" (i.e., where the target object is _implicitly_ passed by the object prefix notation). So... >>>> 2) Combining type and module into a single "class" construct > >>Clearly these two things (prefix notation and type=module) are >>not essential to OOP, since there are several "true" OOP languages >>that don't have them. Nevertheless, if one finds these particular >>"look and feel" characteristics useful, one possibility I have seen >>is to have exactly one (tagged) type per package, and use the package >>name as the equivalent of the "class" name. The actual type name >>is then something innocuous like "object" or "class" or >>some such thing. This gives you both a prefix-like >>notation (e.g. pkg.operation(param1, param2, ...)) and >>provides the one-type-per-module organization. This is precisely the approach that we are using in our OOD courses. It simply removes the need to contrive distinct names for the package and the object's type. I first saw this technique in Colin Atkinson's textbook, "Object-Oriented Reuse, Concurrency, and Distribution" where he addresses how to map DRAGOON's class construct to standard Ada 83 syntax. Note that the technique works similiarly for both Ada 83 and 9X. This naming convention goes further to combat the superficial distinctions that often result between package and type names: package FIFO is package Stacks is package Motor_Vehicle is type Queue is ... type Stack is ... type MV is ... (synonyms) (pluralization) (acronyms and abbreviations) When one desires a "type = module" semantics, such an approach is very appropriate. John Riley responded to Tucker's remarks with an example: >I think your suggestion is this: > >Package X is > type object is ?whatever?; > Procedure OP1 (Q : object); >end X; This is indeed the basic approach. However, several other naming conventions may be introduced to further remove arbritrary distinctions in the implementations. I'll take the liberty to restructure and complete John's short example: package X is -- Represents a class X identified in OOA/OOD type Object is tagged limited private; -- Represents a "root class" procedure Create (Instance : in out Object); -- "constructor" P1 : in Integer); procedure Modify (Instance : in out Object; -- "modifier" P1 : in Integer; function P1 (Instance : Object) return Integer; -- (direct) "selector" private type Object is tagged record P1 : Integer; end record; end X; As with many Ada 83 OOD methods, we use a private type to enforce abstraction and encapsulation principles. In Ada 9X, we can use a _tagged_ private type to begin an inheritance hierarchy. Note that each operation specification must give some name to the formal parameter that represents the target object. Since this parameter is also often arbitrarily named, we can simply pick one and standardize on it. We use the name "Instance." Smalltalk programmers may use "Self," and C++ programmers "this." In any event, standardizing on one name further supports the desire to not have to worry about it in the first place. John also poses the question, >Don't I still need to pass the object as a parameter? The answer is, yes, you do. But by structuring packages in this way, the following syntax results in client code: with X, Text_IO; procedure Some_Client is An_Object : X.Object; P : Integer; begin X.Create (Instance => An_Object, P1 => 7); X.Modify (An_Object, P1 => 3); P := X.P1 (An_Object); Text_IO.Put ("The value of P1 is: "); Text_IO.Put ( Integer'IMAGE(P) ); end Some_Client; We see that the general syntax for declaring such objects is: target_instance : class_name.Object; and the general syntax for "sending messages" is: class_name.operation_name (target_instance, other_parameters); So this technique does provide for a sort of prefixing that John and others may be looking for. The difference is that each operation is prefixed, not by the object name, but by the object's _class_ name. I think that this approach addresses the basic premise of John's concerns, which is to "emphasize the connection between objects and operations." This technique actually goes a step further in that it addresses the connection between objects _and their classes_, which assists in undertanding the modularity and visibility of objects and classes as well. The syntax always documents the "class package" from which an object has been generated and where the object's operations are defined. This particular subject happens to be the theme of a paper that I will be presenting at Tri-Ada in September. Anyone that is interested may contact me by E-Mail for more details. -- Gary J. Cernosek Fastrak Training Inc. Houston Office: (713) 280-4768 E-mail: cernosek@source.asset.com