comp.lang.ada
 help / color / mirror / Atom feed
From: Brian Rogoff <bpr@shellx.best.com>
Subject: Re: Some questions on a library design
Date: 1997/06/20
Date: 1997-06-20T00:00:00+00:00	[thread overview]
Message-ID: <Pine.SGI.3.95.970620101335.12319A-100000@shellx.best.com> (raw)
In-Reply-To: 33AA872C.3611@gsfc.nasa.gov


On Fri, 20 Jun 1997, Stephen Leake wrote:
> Brian Rogoff wrote (in part):
> > Absolutely. Let me provide a real piece of code, so I can illustrate a bit
> > better what I am trying to do, and we can really see if there is a problem
> > or I am just clueless (or both ;-)
> > 
> > with AGL.Basic_Types;
> > with AGL.Input_Iterators;
> > with AGL.Output_Iterators;
> > with AGL.Forward_Iterators;
> > with AGL.Bidirectional_Iterators;
> > 
> > generic
> > package AGL.Lists.Iterators is
> >     type Iterator_Type is
> >        record
> >            Node: Cell_Ptr := null;
> >        end record;
> > 
> >     function Start( L: List_Type ) return Iterator_Type;
> >     function Finish( L: List_Type ) return Iterator_Type;
> >     function "=" ( I: Iterator_Type; J: Iterator_Type ) return Boolean;
> >     procedure Next( I: in out Iterator_Type );
> >     procedure Prev( I: in out Iterator_Type );
> >     function Get_Value( I: in Iterator_Type ) return Value_Type;
> >     procedure Set_Value( I: in Iterator_Type; V: in Value_Type );
> >     function Get_Pointer( I: in Iterator_Type ) return Value_Ptr;
> > 
> >     package Input_Iterators is
> >       new AGL.Input_Iterators(Value_Type,
> >                           Iterator_Type,
> >                           Next,
> >                           Get_Value
> >                           );
> >     package Output_Iterators is
> >       new AGL.Output_Iterators(Value_Type,
> >                                Iterator_Type,
> >                                Next,
> >                                Set_Value
> >                                );
> > ... -- omitted for brevity
> > end AGL.Lists.Iterators;
> > 
> > In the Iterators package for the Lists container, I instantiate all of the
> > possible Iterator signatures (Input, Output, Forward, Bidirectional) that a
> > list supports, so that a client can get at it without doing the
> > instantiation herself. Now, if we could alternate public and private parts
> > of a package, I could move my Iterator_Type to the private part of the
> > package, and then put those signature instantiations after that. (Ada
> > newbie quiz: why doesn't it work if we make Iterator_Type private?).
> 
> Because generic instantiations require the full type definition (RM
> 13.14 (5)). 

Correct, though you could have said "My name is Freeze, remember it well." 
in honor of the latest proof that form beats substance to come out of
Hollywood :-).

> However, you can move the instantiations into a child
> package(s); they can then see the full private type. If you put each
> instantiation in its own child package, the user can choose which ones
> she needs.

Sometimes the user of a library does not want to have to spell out
explicitly (read "manually instantiate") every package they use. In 
my experience, a typical section of STL code needs lots of these iterator
signatures instantiated, and thats why I manually instantiated all of them 
in the Iterators child package. Now, if we move the instantiations to a
(generic) child package

generic 
package AGL.Sets.Iterators.Output_Iterators is
    package Signature is 
        new AGL.Output_Iterators( Value_Type, Iterator_Type, Next,
                                  Set_Value );
end AGL.Sets.Iterators.Output_Iterators;

this adds several generic instantiations (mercifully, with no parameters), 
each with a new package Signatures for each Container.Iterator
instantiation. In a design which IMO is already a bit too heavy on client
side instantiations, I would have to say I find this unacceptable, and 
would rather have that ugly public Iterator_Type in the Iterators child 
package :-(. 

I tried the approach in some test code, and I have to say that even C++
STL is far clearer. I don't mind explicit instantiation, since Ada generics 
seem to work as advertised (unlike C++ templates), but I'd like to be 
able to hide it sometimes, and I think that that leads to clearer code. So
far the alternatives are not appealing.

Also, note how in your proposal that superfluous package we needed to
instantiate in the child because we had to make the child generic.
Wouldn't you rather have written 

generic
package AGL.Sets.Iterators.Output_Iterators is 
    new AGL.Output_Iterators( Value_Type, Iterator_Type, Next, Set_Value );

instead? It seems like something like this would be generally useful.

> This is one reason the interleaving of private and public
> parts is not needed in Ada; child packages give you some of the same
> capabilities.

Well, you could argue that almost nothing in Ada is really needed. Child 
packages are excellent, but alone they do not seem provide what I want. 
All of this explicit instantiation makes me pine for ML :-).

-- Brian






  reply	other threads:[~1997-06-20  0:00 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-06-16  0:00 Some questions on a library design Brian Rogoff
1997-06-17  0:00 ` Robert A Duff
1997-06-17  0:00   ` Brian Rogoff
1997-06-18  0:00     ` Robert A Duff
1997-06-18  0:00       ` Brian Rogoff
1997-06-20  0:00         ` Stephen Leake
1997-06-20  0:00           ` Brian Rogoff [this message]
1997-06-21  0:00   ` Nick Roberts
1997-06-22  0:00     ` Robert Dewar
1997-06-23  0:00     ` Tucker Taft
1997-06-20  0:00 ` Tucker Taft
replies disabled

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