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,fede738cdda9b386 X-Google-Attributes: gid103376,public From: "Matthew Heaney" Subject: Re: Ada OO Terminology Date: 1999/08/06 Message-ID: <37aae129@news1.us.ibm.net> X-Deja-AN: 509577859 Content-transfer-encoding: 7bit References: <37A0A0F9.55CC@radium.ncsc.mil> X-Trace: 6 Aug 1999 13:20:41 GMT, 32.101.8.115 Organization: Global Network Services - Remote Access Mail & News Services X-Notice: should be reported to postmaster@ibm.net Content-Type: text/plain; charset="US-ASCII" Mime-version: 1.0 Newsgroups: comp.lang.ada X-Complaints-To: postmaster@ibm.net Date: 1999-08-06T00:00:00+00:00 List-Id: In article <37A0A0F9.55CC@radium.ncsc.mil>, Tim Kremann wrote: > 1. Typing, is it dynamically checked or just statically? Ada, like C++ and Eiffel, is a statically-typed languge. > 2. Dynamic Binding of Objects and Methods? Yes, for those operation invokations explicitly identified as such, dynamic binding occurs. Otherwise, operation calls are bound statically. Static binding is the default. "Explicit identification" of a dynamic call means this: you invoke a "primitive operation" of the type, on a "class-wide" object of that type. Example: generic type Item_Type is private; package Stacks is type Root_Stack_Type is abstract tagged limited private; procedure Push (Item : in Item_Type; On : in out Stack_Type) is abstract; ... end Stacks; The operation Push is "primitive" for all stack types in the stack class, because it 1) takes a Stack_Type as a parameter, and 2) is declared in the same package (spec) as the declaration of the type. So if you see this: package Integer_Stacks is new Stacks (Integer); use Integer_Stacks; procedure Do_Something (Stack : in out Root_Stack_Type'Class) is begin ... Push (1234, On => Stack); ... end Do_Something; The invokation of the Push operation is dynamic, because 1) Push is primitive for Stack, and 2) the object is class-wide (here it's of type Root_Stack_Type'Class). The Ada95 philosophy is to give the *caller* explicit control of dynamic binding of (primitive) operations. For example, let's create a specific stack type: generic Max_Depth : in Positive; package Stacks.Bounded_G is type Stack_Type is new Root_Stack_Type with private; procedure Push (Item : in Item_Type; On : in out Stack_Type); ... end Stacks.Bounded_G; Now let's instantiate it: with Stacks.Bounded_G, Integer_Stacks; package Integer_Stacks.Bounded is new Stacks.Bounded_G (Max_Depth => 10); use Integer_Stacks.Bounded; Now let's use it: declare Stack : Integer_Stacks.Bounded.Stack_Type; begin Push (1234, On => Stack); ... end; Note that Push is of course primitive for stacks (as we explained before), but the invokation here is *static*, not dynamic. There is no reason to dynamically bind Push, because you know everything you need to know about what type of stack this is (it's a bounded stack). If for whatever reason you the caller decide that you want to invoke Push dynamically, then of course you can do that too: declare Stack : Integer_Stacks.Bounded_Stack.Stack_Type; begin Push (1234, On => Root_Stack_Type'Class (Stack)); ... end; Here the caller decides to invoke Push dynamically by explicitly converting the bound stack to a class-wide type, which is Ada's way of saying loud and clear to a reader that This Operation Is Being Called Dynamically. (In the example above, you could also have converted the Stack to type Bounded.Stack_Type'Class. Any ancestor class-wide type will do equally well.) > 3. Runtime access to Method names, class names, instance names. In Ada-speak, I think you mean "runtime access to operation names, type names, and instance names." The answer is no. But give an small example in another language of what you're trying to. > 4. Does Ada have forwarding and metaclasses? I don't know what you mean by forwarding. Follow up this post with an explaination and a small example in another language, and I'll respond. As for "metaclasses," do you mean a la Smalltalk, in which classes are really objects? If you mean that, then the answer is no. But state data hidden in the package body mostly takes care of that job. Define what you mean by a "metaclass," include small example in some other language, and I'll respond. Better yet, instead of asking "Does Ada95 have these language features?", say what it is that you're trying to do. Common problems have different solutions in different programming languages, by using different mechanisms. > 5. Can you access super methods? Do you mean "call the operation of the type's parent"? The answer is yes, by converting the object to the parent type, and then invoking the operation. For example, suppose I have some special kind of bounded stack: generic package Stacks.Bounded_G.Special_G is type Stack_Type is new Bounded_G.Stack_Type with private; procedure Push (...); end; Now let's call the parent Push operation: declare Stack : Integer_Stacks.Bounded.Special.Stack_Type; begin Push (1234, On => Bounded.Stack_Type (Stack)); ... end; Even though the Stack object is of specific type Special.Stack_Type, which has its own version of Push, the Push operation of its parent is invoked. No, Ada95 does not have a way to say "invoke my parent's operation." Something like this was proposed for the language revision: Push (1234, On => Special.Stack_Type'Parent (Stack)); but it didn't make the cut. Oh, well. > 6. Is there a concept of root class? Not in the Objective-C, Smalltalk (Java too?) sense. You the programmer are responsible for creating the root of your type hierarchy (as we did in our stack example, aka Root_Stack_Type.) > 7. Does there exist the concept of reciever and self > referencing (this, me)? Not really, because it's not necessary. Ada95 uses parameter notation instead of "distinguished reciever" syntax, so the object that is the recipient of the message is already identified explicitly. For example, here's the implementation of the Push operation for a bounded stack: procedure Push (Item : in Item_Type; On : in out Stack_Type) is Stack : Stack_Type renames On; -- Stack is a nicer name inside the op begin pragma Assert (Stack.Depth < Max_Depth); Stack.Depth := Stack.Depth + 1; Stack.Items (Stack.Depth) := Item; end Push; The object "Stack" (same as "On") is the recipient of the Push message. You don't need a "this" to name it, because the stack object already has a name. You can rename the components of the stack, so you don't have to explicitly select the attribute, ie procedure Push (Item : in Item_Type; On : in out Stack_Type) is Depth : Natural renames On.Depth; Item : Item_Array renames On.Items; begin pragma Assert (Depth < Max_Depth); Depth := Depth + 1; Items (Depth) := Item; end; > 8. Does ada have class variables? Yes (if I understand your meaning). They are declared as (static) objects in the package: package body Stacks.Bounded_G is Push_Count : Natural := 0; procedure Push (...) is ... begin ... Push_Count := Push_Count + 1; end Push; The object Push_Count is a "class-variable," in the sense that it's shared among all instances of bounded stacks. You have to be careful of your terminology, however, because "class" in Ada95 has a very specific meaning that it not the same as in other languages. Instead of calling a type a "class", as is done (unfortunely) in other languages, in Ada95 we call a type a "type". (Duh.) > 9. Garbage collection? The language doesn't require a garbage collector, but the language was designed to facilitate its inclusion should a vendor decide to do so. However, in the real-time, safetly-critical domain, the developer must have explicit control of program behavior, including the time and space semantics of allocation and deallocation. For that reason, very few members of the Ada community have been interested in automatic garbage collection. That being said, the language does have features that allows the writer of an abstration to automatically reclaim memory when there are no more references to the object. These "controlled" types do just about everything you need to provide automatic garbage collection for a type. > 10. Are classes first class objects? In Ada-speak, you mean to say "Are types first class objects?" The answer is no. However, this is one of those times where you have to say what it is you're trying to accomplish. For that problem, the language probably has other mechanisms to solve it. > 11. Does Ada have persistent Object support? You can effect a form of persistency by using the Distributed Systems Annex (I think). You can also use the streams facility and controlled types to build it yourself. > From my reading so far I have the muddled impression > that Classes = Types and Encapsulation = Packaging. That's about right, although you should try to grok what an Ada95 "class" is too. > What is instantiation in Ada? The term "instatiation" in Ada does not mean "create an instance (object) of a type," as it does it other languages. (We just say, "create an instance of the type.") The term "instantiation" in Ada refers to the act of "reifying" a generic package, ie with Stacks; package Integer_Stacks is new Stacks (Integer); You "instantiate" the generic package Stacks on Integer, thus creating a (non-generic) package, Integer_Stacks, that provides types and operations you can actually use. > If there is an on-line source for answering these questions? -- very good; has some FAQs -- good and getting better There are more, but you can just follow the links from adahome.