comp.lang.ada
 help / color / mirror / Atom feed
* Separating Interface and Implementation
@ 1996-11-03  0:00 Matthew Heaney
  0 siblings, 0 replies; only message in thread
From: Matthew Heaney @ 1996-11-03  0:00 UTC (permalink / raw)



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




^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~1996-11-03  0:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-11-03  0:00 Separating Interface and Implementation Matthew Heaney

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox