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,b3301132bddf951d,start X-Google-Attributes: gid103376,public From: mheaney@ni.net (Matthew Heaney) Subject: Separating Interface and Implementation Date: 1996/11/03 Message-ID: #1/1 X-Deja-AN: 194159360 organization: Estormza Software content-type: text/plain; charset=ISO-8859-1 mime-version: 1.0 newsgroups: comp.lang.ada Date: 1996-11-03T00:00:00+00:00 List-Id: I think the intended way in Ada 95 to separate the interface of an ADT from its implementation is to use a combination of generics and inheritance. In the case of data structures, the idea is to let the instantiator of the generic choose the implementation, because he knows more about the data he's going to populate the data structure with, and he the instantiator should be able to select the implementation that has the time and space semantics he desires. This is also the way make a queue prioritized (for example), by choosing an implementation that is itself prioritized. The queue itself shouldn't care. It's also the way to implement a data structure as bounded or unbounded; the data structure (interface) doesn't care. Actually, I'll qualify this by saying that there'll probably be a subtype (of some abstract supertype) that adds a size discriminant. In Ada 95, we can add discriminants (and take them away). Cool, huh? For example, generic type T is private; type T_Collection is private; with procedure Add (Item : in T; To : in out T_Collection) is <>; ... package Queues is type Queue is [tagged] [abstract] private; -- something like that (no Ada 95 compiler yet!) procedure Add (Item : in T; To : in out Queue); ... private type Queue is record Collection : T_Collection; ... end record; end; Any collection that has the specified operations can be used to implement the queue. So I might decide to use a list to implement the queue. And the list I supply as implementation may be prioritized, so that the queue itself becomes prioritized. This is how we combine components from different vendors - by plugging them in using genericity. If the actual operations of the formal type visible at the point of instantiation match those of the formal operations, then the instantiation is simple - we just take the defaults (note the specification of the generic formal subprograms). If the generic actual operations don't match, then the instantiator can supply a bit of "software glue" by having (small) generic actual subprograms that call the "real" operations of the generic actual type. Yes, it's true that the instantiator has to do a bit more work to instantiate the component, but there will be far fewer units to maintain, and the instatiation itself can be made easier by using signiture packages. Beats starting over from scratch every time we need a component that's slightly different from the ones we already have, right? The idea is to have simple components that clients can mix and match as they please. See the articles in the past couple years in TRI-Ada proceedings by the guys at the Swiss Federal Institute of technology for more published info. -------------------------------------------------------------------- Matthew Heaney Software Development Consultant mheaney@ni.net (818) 985-1271