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.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,baa6871d466e5af9 X-Google-Attributes: gid103376,public From: mheaney@ni.net (Matthew Heaney) Subject: Re: AQ&S Guidance on pragma Elaborate_Body Date: 1997/04/29 Message-ID: #1/1 X-Deja-AN: 238313227 References: <528878564wnr@diphi.demon.co.uk> <5jabeq$3ltk@info4.rus.uni-stuttgart.de> <5jfukp$lda@top.mitre.org> <33660F4B.1B45@sprintmail.com> Organization: Estormza Software Newsgroups: comp.lang.ada Date: 1997-04-29T00:00:00+00:00 List-Id: In article <33660F4B.1B45@sprintmail.com>, johnvolan@sprintmail.com wrote: >> I'm talking about just a pair of abstract data types that are intimately >> related. But I sense that you and the other posters are talking about >> large packages (say, a subprogram library such as binding). > >"Co-encapsulation," as I like to call it, has a cost: Loss of >abstraction. Because both types have visibility to each other's private >features, there is no way to enforce each to adhere to the discipline of >only calling the other's public interface. This affects >understandability: Readers must understand what both types are doing, >internally, before they can be sure they know what either type is doing. > >Of course, if it's just "a pair of abstract data types that are >intimately related", and that's all there is to it, then the cost of >abstraction-loss is relatively small, so co-encapsulation may be a >reasonable option. That's all I was saying: a pair of ADTs that are intimately related. Here's an example. In order to efficiently implement an active iterator, that iterator has to have knowledge of the representation of the data structure. For a bounded stack, I would do this: type Bounded_Stack is new Root_Stack with private; type Bounded_Stack_Iterator (Stack : access Bounded_Stack) is new Root_Stack_Iterator with private; ... private subtype Item_Array_Range is Positive range 1 .. Size; type Item_Array is array (Item_Array_Range) of Stack_Item; type Bounded_Stack is new Root_Stack with record Items : Item_Array; Top : Natural := 0; end record; type Bounded_Stack_Iterator (Stack : access Bounded_Stack) is new Root_Stack_Iterator with record Index : Positive; end record; end Stacks_G.Bounded_G; I'm certainly not advocating large packages. It's just that very often, there are a small number of types (read: 2) that need to know about each other's representation, or that one needs the know the represenation of the other (the iterator above). This is just the concept of a friend in C++: to implement that in Ada, you put the types together in the same package. No big deal. There is NO loss of abstraction when the stack and its iterator are co-located in the same package; the abstractions were meant to be used together. I don't subscribe to these gloom and doom scenarios about putting types together; this is how the language was _intended_ to be used. And it's certainly true that this affects understandability: it makes it MORE understandable when the "declaration span" is minimized. This is analogous to using a declare block to move declaration of an object as close as possible to its use. I don't understand why a client needs to understand "internally" the Bounded_Stack and its iterator to use it: Do_Not_Need_Knowledge_Of_Representation_To_Use: declare The_Stack : aliased Bounded_Stack; The_Iterator : Bounded_Stack_Iterator (The_Stack'Access); begin ... while not Is_Done (The_Iterator) loop Advance (The_Iterator); end loop; end Do_Not_Need_Knowledge_Of_Representation_To_Use; What's so difficult about this? Matt -------------------------------------------------------------------- Matthew Heaney Software Development Consultant (818) 985-1271