comp.lang.ada
 help / color / mirror / Atom feed
* Some questions on a library design
@ 1997-06-16  0:00 Brian Rogoff
  1997-06-17  0:00 ` Robert A Duff
  1997-06-20  0:00 ` Tucker Taft
  0 siblings, 2 replies; 11+ messages in thread
From: Brian Rogoff @ 1997-06-16  0:00 UTC (permalink / raw)



Hi,
	In the process of writing a collection library for Ada I have 
encountered a few stumbling blocks that I hope can be removed. The library 
is rather like the C++ STL, and so I avoid dynamic dispatching 
*completely*. I have also avoided tagged types although that is not
strictly necessary.

	One of the containers in the library is a generic set, whose 
specification looks like this 

generic
    type Element_Type is private;
    with function "<" ( Left, Right : Element_Type ) return Boolean is <>;
package AGL.Sets is
    type Set_Type is private;
    type Value_Type is private;
    function Is_Member ( Set : Set_Type; Key : Value_Type ) return Boolean;
    ... etc. ...
end AGL.Sets;

and a child package Iterators which instantiates its own textually nested 
packages corresponding to the kinds of traversal it supports

generic
package AGL.Sets.Iterators is
    type Iterator_Type is private;

    function Start ( Set : Set_Type ) return Iterator_Type;
    function Finish ( Set : Set_Type ) return Iterator_Type;

    ... etc. ...
    package Forward_Iterators is
      new AGL.Forward_Iterators(Value_Type, Iterator_Type, Value_Ptr,
                                Next, Get_Value, Set_Value, Get_Pointer);

    package Bidirectional_Iterators is
      new AGL.Bidirectional_Iterators(Value_Type,Iterator_Type,Value_Ptr,
                                      Next,Prev,Get_Value,Set_Value,
                                      Get_Pointer,"=");

end AGL.Sets.Iterators;

The packages AGL.Whatever_Iterators are null bodied generic signature 
packages, and their instantiations in the Whatever_Container.Iterators 
package are "plugged" in to the various algorithms which only know about 
the iterator signature.

I have a Red_Black_Trees package which also has an Iterators child 
package, and I would like to use them to implement the Sets/Sets.Iterators 
(and of course Maps/Maps.Iterators, Multisets/Multisets.Iterators, etc.). 
I'd like for aesthetic reasons (;-)) to keep this implementation choice 
private (I'll have a Splay_Trees package any time now). However, I am 
having a bit of trouble figuring out how to do this; so far I just declare
the Red_Black_Trees package in the public part of Sets' spec, and do the
same with Red_Black_Trees.Iterators in Sets.Iterators, like so:

generic
    type Element_Type is private;
    with function "<" ( Left, Right : Element_Type ) return Boolean is <>;
package AGL.Sets is
    -- Our Set_Type is implemented as a Red_Black_Tree
    package Trees is new AGL.Red_Black_Trees( Element_Type => Element_Type,
                                              Insert_Always => False,
                                              "<" => "<" );

    subtype Set_Type is Trees.Tree_Type;
    subtype Value_Type is Trees.Value_Type;
    subtype Value_Ptr is Trees.Value_Ptr;

    ... etc. ...
end AGL.Sets;

generic
package AGL.Sets.Iterators is
    package Tree_Iterators is new Trees.Iterators;
    subtype Iterator_Type is Tree_Iterators.Iterator_Type;
    ... etc. ...
end AGL.Sets.Iterators;

I find it inelegant in that I'd prefer that representation information be 
restricted to the private part of a package, even though that seems to 
be necessary in order to instantiate the signature packages in 
Sets.Iterators. Any suggestions on how to do this better?

Also, I thought it would be cool if I could do a partial instantiation of 
a generic package to create a new generic package with fewer parameters,
like 

generic package Sets is new Red_Black_Trees ( Insert_Always => False );
generic package Multisets is new Red_Black_Trees ( Insert_Always => True );

Am I missing something, i.e., is there a good approximation to this
functionality in Ada?

-- Brian






^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Some questions on a library design
  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-21  0:00   ` Nick Roberts
  1997-06-20  0:00 ` Tucker Taft
  1 sibling, 2 replies; 11+ messages in thread
From: Robert A Duff @ 1997-06-17  0:00 UTC (permalink / raw)



In article <Pine.SGI.3.95.970616161142.25177A-100000@shellx.best.com>,
Brian Rogoff  <bpr@shellx.best.com> wrote:
>Hi,
>	In the process of writing a collection library for Ada I have 
>encountered a few stumbling blocks that I hope can be removed. The library 
>is rather like the C++ STL, and so I avoid dynamic dispatching 
>*completely*. I have also avoided tagged types although that is not
>strictly necessary.

If I were doing it, I think I would use tagged types and inheritence.
Let the client decide whether dispatching calls are too inefficient.
One nice thing about Ada, is that you can choose to use dispatching or
not, on a call-by-call basis.

>...However, I am 
>having a bit of trouble figuring out how to do this; so far I just declare
>the Red_Black_Trees package in the public part of Sets' spec, and do the
>same with Red_Black_Trees.Iterators in Sets.Iterators, like so:

Would it help to pass in a generic formal package?

- Bob




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Some questions on a library design
  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-21  0:00   ` Nick Roberts
  1 sibling, 1 reply; 11+ messages in thread
From: Brian Rogoff @ 1997-06-17  0:00 UTC (permalink / raw)



On Tue, 17 Jun 1997, Robert A Duff wrote:
> Brian Rogoff  <bpr@shellx.best.com> wrote:
> >Hi,
> >	In the process of writing a collection library for Ada I have 
> >encountered a few stumbling blocks that I hope can be removed. The library 
> >is rather like the C++ STL, and so I avoid dynamic dispatching 
> >*completely*. I have also avoided tagged types although that is not
> >strictly necessary.
> 
> If I were doing it, I think I would use tagged types and inheritence.
> Let the client decide whether dispatching calls are too inefficient.
> One nice thing about Ada, is that you can choose to use dispatching or
> not, on a call-by-call basis.

There is nothing stopping the client from storing tagged types in the 
AGL collections, and dispatching on them in the client code. But why 
should I have dispatching in the library when all of the container types 
are known statically? 

In any case, I am deliberately copying the STL, in which dynamic dispatch, 
benefits and all, is avoided. You may prefer the Booch components to the 
AGL, and there is room for both (and more!).
 
> >...However, I am 
> >having a bit of trouble figuring out how to do this; so far I just declare
> >the Red_Black_Trees package in the public part of Sets' spec, and do the
> >same with Red_Black_Trees.Iterators in Sets.Iterators, like so:
> 
> Would it help to pass in a generic formal package?

I'm not sure I understand your suggestion. Do you mean pass in a generic
formal package (which would get Red_Black_Trees or Splay_Trees) to the
Sets package, and then do a bunch of subtypes and renamings to get the Sets 
interface? Thats a possibility I have considered, and one that the authors 
of the RPI Ada STL implemented for deriving Queues from other containers 
(they call it "Adaptors") but I am not convinced that this is best, mainly 
because I think that in order to use the generic formal package approach,
you'd want to bundle it up the actual representation with a signature
package, something like 

package RB_Trees is new AGL.Red_Black_Trees (...);
package Set_Reps is new AGL.Set_Signatures( Set_Type => RB_Trees.Tree_Type, 
                                        Element_Type => RB_Trees.Element_Type,
                                        ... etc... );
package My_Sets is new AGL.Sets ( Set_Reps );

leads to too many unhelpful instantiations by the client. 

If that wasn't what you were suggesting, my apologies, and please describe 
what you mean.

Ideally (IMO), the client should be able to create a new set package by
going 

package My_Sets is new AGL.Sets ( Element_Type => Integer, "<" => "<" ); 

and all of the iterators for the set with

package My_Sets_Iters is new My_Sets.Iterators;

without even knowing about red-black trees, splay trees, hash tables, or 
whatever the implementation is, unless of course they want to change it.

What I have been wishing for is a way to define a new generic package in 
terms of an existing one by instantiating some of its parameters. Renaming 
is not quite right because I want the "renamed" package (say AGL.Sets) to
be generic, and I may want to fill in some of the parameters of the generic 
package being renamed (AGL.Red_Black_Trees has a Boolean "Insert_Always" 
flag whose value determines whether the package describes a set or a
multiset).

A while ago, Norman Cohen suggested "package parts" as a solution to the 
infamous "withing problem". There have been quite a few times while I've 
been crafting at this library that I also wished for the ability to
interleave specs and private parts, so I certainly appreciate that
suggestion a lot more now, outside of the context of package spanning
mutually recursive specs!

-- Brian






^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Some questions on a library design
  1997-06-18  0:00     ` Robert A Duff
@ 1997-06-18  0:00       ` Brian Rogoff
  1997-06-20  0:00         ` Stephen Leake
  0 siblings, 1 reply; 11+ messages in thread
From: Brian Rogoff @ 1997-06-18  0:00 UTC (permalink / raw)



On Wed, 18 Jun 1997, Robert A Duff wrote:
> In article <Pine.SGI.3.95.970617154248.6950A-100000@shellx.best.com>,
> Brian Rogoff  <bpr@shellx.best.com> wrote:
> >There is nothing stopping the client from storing tagged types in the 
> >AGL collections, and dispatching on them in the client code. But why 
> >should I have dispatching in the library when all of the container types 
> >are known statically? 
> 
> I wasn't suggesting that you have dispatching in the library.  I was
> suggesting that the client be able to *choose* dispatching, by creating
> (e.g.) a "vector of sequence'Class", where sequence is a superclass of
> vector, list, deque, etc., and then the client could iterate through
> that vector, and dispatch to the appropriate *whatever* for that class.
> 
> But the client that just wants a vector of lists would get *zero*
> dispatching calls.

I'd have to think about that approach some more. Sounds like a reasonable
alternative approach. Of course, you'd still parametrize (with generics)
the element types and comparison operations too.

> I admit, I haven't thought this through.  But it seems like Ada's
> ability to choose dispatching-vs-not-dispatching at the call site should
> allow you to do what STL does in terms of efficiency, while still
> *allowing* polymorphic calls to sequence operations.  In C++, you have
> to choose virtual-or-not at the declaration of the function, which
> constrains you a bit.

Actually, there was a raging multi-NG debate on the efficiency of the STL 
which casts some doubt on the speed claims. The important reasons to 
copy the STL for me are more "social" than "technical"; lots of people 
use C++ (including me), so commonality of libraries saves precious brain
space :-). 

> >In any case, I am deliberately copying the STL, in which dynamic dispatch, 
> >benefits and all, is avoided. You may prefer the Booch components to the 
> >AGL, and there is room for both (and more!).
> 
> Fair enough.  I'm just wondering if one can't get the best of both
> worlds in Ada.

Now I'm wondering the same thing...

> >I'm not sure I understand your suggestion. Do you mean pass in a generic
> >formal package (which would get Red_Black_Trees or Splay_Trees) to the
> >Sets package, ...
> 
> Yeah, something like that.  I guess I don't understand what you're
> trying to do.  Do you want the client to be able to choose which sort of
> set is used?  Or not?

Originally not, although obviously the client with source code should be
able to change the representation, and I'll make my sources available when
they are ready. The C++ STL uses red-black trees to represent sets,
multisets, maps, and multimaps (all of these are *ordered*, the SGI STL
also supports hashed/unordered versions of all of these) so I am following 
its lead for now. I had hoped that I could avoid making the client do lots 
of instantiations by being clever (instantiating each iterator class in 
the child Container.Iterators of Container, see the end of this message)
but I am being thwarted so far.

Since I am having trouble doing what I wanted to do, I may actually just go
ahead and have a representation package parameter. I'm thinking that its
use would be something like this:

package Integer_RBTrees is 
    new Red_Black_Trees(Integer,"<",Insert_Always=>False);

package Integer_Set_Rep is 
    new AGL.Set_Signature( Integer_RBTrees.Tree_Type,
                           Integer_RBTrees.Value_Type,
                           ... etc ... );

package Integer_Set is new AGL.Sets( Integer, "<", Integer_Set_Rep );

which is a bit heavier than what I wanted: 

package Integer_Set is new AGL.Sets( Integer, "<" );

since instantiating the signature package requires that the client provide 
a lot of parameters, but has the advantage that the client can select the 
set representation.

> >A while ago, Norman Cohen suggested "package parts" as a solution to the 
> >infamous "withing problem". There have been quite a few times while I've 
> >been crafting at this library that I also wished for the ability to
> >interleave specs and private parts, so I certainly appreciate that
> >suggestion a lot more now, outside of the context of package spanning
> >mutually recursive specs!
> 
> Maybe just alternating public and private parts of a package would
> suffice here?

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
                               );
    package Forward_Iterators is
      new AGL.Forward_Iterators(Value_Type,
                            Iterator_Type,
                            Value_Ptr,
                            Next,
                            Get_Value,
                            Set_Value,
                            Get_Pointer
                            );
    package Bidirectional_Iterators is
      new AGL.Bidirectional_Iterators(Value_Type,
                                  Iterator_Type,
                                  Value_Ptr,
                                  Next,
                                  Prev,
                                  Get_Value,
                                  Set_Value,
                                  Get_Pointer,
                                  "=");
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?). And
while that is helpful here, it is *way* more helpful with respect to your
suggestion about formal package parameters, since I could then instantiate
Set_Signature inside Red_Black_Trees (and Splay_Trees, and others...) and
avoid that onerous instantiation by the client. 

-- Brian





^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Some questions on a library design
  1997-06-17  0:00   ` Brian Rogoff
@ 1997-06-18  0:00     ` Robert A Duff
  1997-06-18  0:00       ` Brian Rogoff
  0 siblings, 1 reply; 11+ messages in thread
From: Robert A Duff @ 1997-06-18  0:00 UTC (permalink / raw)



In article <Pine.SGI.3.95.970617154248.6950A-100000@shellx.best.com>,
Brian Rogoff  <bpr@shellx.best.com> wrote:
>There is nothing stopping the client from storing tagged types in the 
>AGL collections, and dispatching on them in the client code. But why 
>should I have dispatching in the library when all of the container types 
>are known statically? 

I wasn't suggesting that you have dispatching in the library.  I was
suggesting that the client be able to *choose* dispatching, by creating
(e.g.) a "vector of sequence'Class", where sequence is a superclass of
vector, list, deque, etc., and then the client could iterate through
that vector, and dispatch to the appropriate *whatever* for that class.

But the client that just wants a vector of lists would get *zero*
dispatching calls.

I admit, I haven't thought this through.  But it seems like Ada's
ability to choose dispatching-vs-not-dispatching at the call site should
allow you to do what STL does in terms of efficiency, while still
*allowing* polymorphic calls to sequence operations.  In C++, you have
to choose virtual-or-not at the declaration of the function, which
constrains you a bit.

>In any case, I am deliberately copying the STL, in which dynamic dispatch, 
>benefits and all, is avoided. You may prefer the Booch components to the 
>AGL, and there is room for both (and more!).

Fair enough.  I'm just wondering if one can't get the best of both
worlds in Ada.

>I'm not sure I understand your suggestion. Do you mean pass in a generic
>formal package (which would get Red_Black_Trees or Splay_Trees) to the
>Sets package, ...

Yeah, something like that.  I guess I don't understand what you're
trying to do.  Do you want the client to be able to choose which sort of
set is used?  Or not?

>A while ago, Norman Cohen suggested "package parts" as a solution to the 
>infamous "withing problem". There have been quite a few times while I've 
>been crafting at this library that I also wished for the ability to
>interleave specs and private parts, so I certainly appreciate that
>suggestion a lot more now, outside of the context of package spanning
>mutually recursive specs!

Maybe just alternating public and private parts of a package would
suffice here?

- Bob




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Some questions on a library design
  1997-06-20  0:00         ` Stephen Leake
@ 1997-06-20  0:00           ` Brian Rogoff
  0 siblings, 0 replies; 11+ messages in thread
From: Brian Rogoff @ 1997-06-20  0:00 UTC (permalink / raw)



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






^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Some questions on a library design
  1997-06-16  0:00 Some questions on a library design Brian Rogoff
  1997-06-17  0:00 ` Robert A Duff
@ 1997-06-20  0:00 ` Tucker Taft
  1 sibling, 0 replies; 11+ messages in thread
From: Tucker Taft @ 1997-06-20  0:00 UTC (permalink / raw)



Brian Rogoff (bpr@shellx.best.com) wrote:

: ...
: Also, I thought it would be cool if I could do a partial instantiation of 
: a generic package to create a new generic package with fewer parameters,
: like 

: generic package Sets is new Red_Black_Trees ( Insert_Always => False );
: generic package Multisets is new Red_Black_Trees ( Insert_Always => True );

: Am I missing something, i.e., is there a good approximation to this
: functionality in Ada?

This is most easily done by defining a new generic that internally
instantiates the generic which has more parameters.  You could make
the inner instantiation visible if you want to be able to pass it
for a formal package parameter.  Alternatively, you could create
wrappers for all of its subprograms, and mark all of these wrappers
with a pragma "inline."

: -- Brian

-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Some questions on a library design
  1997-06-18  0:00       ` Brian Rogoff
@ 1997-06-20  0:00         ` Stephen Leake
  1997-06-20  0:00           ` Brian Rogoff
  0 siblings, 1 reply; 11+ messages in thread
From: Stephen Leake @ 1997-06-20  0:00 UTC (permalink / raw)



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
>                                );
>     package Forward_Iterators is
>       new AGL.Forward_Iterators(Value_Type,
>                             Iterator_Type,
>                             Value_Ptr,
>                             Next,
>                             Get_Value,
>                             Set_Value,
>                             Get_Pointer
>                             );
>     package Bidirectional_Iterators is
>       new AGL.Bidirectional_Iterators(Value_Type,
>                                   Iterator_Type,
>                                   Value_Ptr,
>                                   Next,
>                                   Prev,
>                                   Get_Value,
>                                   Set_Value,
>                                   Get_Pointer,
>                                   "=");
> 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)). 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. 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.

> -- Brian

-- 
- Stephe




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Some questions on a library design
  1997-06-17  0:00 ` Robert A Duff
  1997-06-17  0:00   ` Brian Rogoff
@ 1997-06-21  0:00   ` Nick Roberts
  1997-06-22  0:00     ` Robert Dewar
  1997-06-23  0:00     ` Tucker Taft
  1 sibling, 2 replies; 11+ messages in thread
From: Nick Roberts @ 1997-06-21  0:00 UTC (permalink / raw)





Robert A Duff <bobduff@world.std.com> wrote in article
<EBxrtu.7v6@world.std.com>...
[...]
> One nice thing about Ada, is that you can choose to use dispatching or
> not, on a call-by-call basis.

In theory, but not often in practice. And in no case is the inefficiency of
the extra tag removed, nor of the dynamic tag checking (and sometimes
dynamic access checking).

Nick.





^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Some questions on a library design
  1997-06-21  0:00   ` Nick Roberts
@ 1997-06-22  0:00     ` Robert Dewar
  1997-06-23  0:00     ` Tucker Taft
  1 sibling, 0 replies; 11+ messages in thread
From: Robert Dewar @ 1997-06-22  0:00 UTC (permalink / raw)



Nick says

<<In theory, but not often in practice. And in no case is the inefficiency of
the extra tag removed, nor of the dynamic tag checking (and sometimes
dynamic access checking).
>>

Several points here. I do not understand the "theory, not often in practice"
comment here. The original post seems exactly correct, and I cannot see Nick's
objection.

"inefficiency of the extra tag removed
"

Also not understandable, there is no requirement in the language for any
"extra tag" here. Some implementations may have various inefficiencies, but
if you are claiming that there is some fundamental inefficiency here, the
basis of this claim is unclear.

"dynamic tag checking"

This is entirely optional, how can you complain about an option?

"dynamic access checking"

This is entirely optional, how can you complain about an option?





^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Some questions on a library design
  1997-06-21  0:00   ` Nick Roberts
  1997-06-22  0:00     ` Robert Dewar
@ 1997-06-23  0:00     ` Tucker Taft
  1 sibling, 0 replies; 11+ messages in thread
From: Tucker Taft @ 1997-06-23  0:00 UTC (permalink / raw)



Nick Roberts (Nick.Roberts@dial.pipex.com) wrote:

: Robert A Duff <bobduff@world.std.com> wrote in article
: <EBxrtu.7v6@world.std.com>...
: [...]
: > One nice thing about Ada, is that you can choose to use dispatching or
: > not, on a call-by-call basis.

: In theory, but not often in practice. 

Actually, most calls in Ada 95 end up being statically bound, whereas
in most other OOP languages, many more calls end up being dynamically
bound, even though there is no good reason for it (and oftentimes a
statically bound call would make more sense semantically as well).

: ... And in no case is the inefficiency of
: the extra tag removed, 

The extra tag imposes a small space expense, but essentially no
time overhead.  You do still have the option of creating untagged 
records in Ada 95, something not available in Java or Smalltalk.

: ... nor of the dynamic tag checking (and sometimes
: dynamic access checking).  

There are various "tag check"s in Ada, but none of them are 
performed on a statically bound call.  

An "access check" checks for null pointers, something quite
different from a "tag check."   There is also something called
an "accessibility check" which is to prevent the creation of
potentially dangling references.

You might want to check your facts a bit...

: Nick.

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~1997-06-23  0:00 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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

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