[comp.lang.ada] Design issue: Generics vs Private types

FMOORE@eg.ti.COM.UUCP (05/27/87)

When should generic packages be used to encapsulate data as
opposed to using packages with private data types?

Consider the following two approachs to protecting data:


generic                              ! package COUNTER is
package COUNTER_TYPE is              ! type C_T is private;
   procedure ZERO;                   !   procedure ZERO (ITEM : out C_T);
   procedure INCREMENT;              !   procedure INCREMENT (ITEM : in out
   procedure DISPLAY;                !                          C_T);
end COUNTER_TYPE;                    !   procedure DISPLAY (ITEM : in C_T);
                                     ! private
package body COUNTER_TYPE is         !   type C_T is some_type ...
DATUM : some_type ...                !  -- data hidden as private type
...-- data hidden within body        ! end COUNTER;
end COUNTER_TYPE;                    !
                                     !
package COUNTER1 is new COUNTER_TYPE;! COUNT1, COUNT2 : COUNTER.C_T;
package COUNTER2 is new COUNTER_TYPE;!
                                     !
COUNTER1.ZERO;                       ! COUNTER.ZERO (COUNT1);
COUNTER2.ZERO;                       ! COUNTER.ZERO (COUNT2);
                         etc.        !


I can imagine that the implementation of these two approaches would
vary from compiler to compiler, especially depending upon how a
compiler implements generics.

However, my interest is in expressing designs.  From the point of
view of good design technique, can one approach over the other be
supported?  If so, what design technique / rules are involved?

Thanks for any insight.
Freeman Moore
FMOORE%ti-eg@relay.cs.net

arny@wayback.UUCP (Arny B. Engelson) (05/29/87)

In article <8705270150.AA06260@ucbvax.Berkeley.EDU>, FMOORE@eg.ti.COM (Freeman Moore - 575-3507) writes:
> When should generic packages be used to encapsulate data as
> opposed to using packages with private data types?
> Consider the following two approachs to protecting data:
> 
> generic                              ! package COUNTER is
> package COUNTER_TYPE is              ! type C_T is private;
>    procedure ZERO;                   !   procedure ZERO (ITEM : out C_T);
>    procedure INCREMENT;              !   procedure INCREMENT (ITEM : in out
>    procedure DISPLAY;                !                          C_T);
> end COUNTER_TYPE;                    !   procedure DISPLAY (ITEM : in C_T);
>                                      ! private
> package body COUNTER_TYPE is         !   type C_T is some_type ...
> DATUM : some_type ...                !  -- data hidden as private type
> ...-- data hidden within body        ! end COUNTER;
> end COUNTER_TYPE;                    !
>                                      !
> package COUNTER1 is new COUNTER_TYPE;! COUNT1, COUNT2 : COUNTER.C_T;
> package COUNTER2 is new COUNTER_TYPE;!
>                                      !
> COUNTER1.ZERO;                       ! COUNTER.ZERO (COUNT1);
> COUNTER2.ZERO;                       ! COUNTER.ZERO (COUNT2);
>                          etc.        !
 
> However, my interest is in expressing designs.  From the point of
> view of good design technique, can one approach over the other be
> supported?  If so, what design technique / rules are involved?
 

On design considerations alone, I would have to vote for using the private
type approach.  Your intentions are a lot more obvious there.  A private
type with a set of operations on it.  Fine.  If you want another counter,
make another variable.  But with the generic package, things look very weird.
A generic package without parameters?!  It takes a while to see that making
another instantiation of the package gives you a new counter.  Generic
packages are supposed to be 'tunable', providing a template that you use to
create unique copies.  Your generic package doesn't do that.  All of it's
copies are the same.  There are no 'tunable' parameters.  You have to create
a whole new package just to get a new counter.  And it makes (conceptually)
an identical copy of all the routines to operate on the new counter.  What a
waste.

P.S. I believe efficiency concerns SHOULD be taken into account when designing
a system.  Your program will be useless if it doesn't meet performance
requirements, no matter how conceptually pleasing the design may be.

- Arny Engelson   {ihnp4,bonnie,clyde}!wayback!arny

Bryan@SIERRA.STANFORD.EDU (Doug Bryan) (05/30/87)

Don't discount generic packages without parameters too soon!!  I think they
have a lot of important uses.  You have to remember that packages can have
state, and getting a new, private (English meaning) state can be important.
Also, issues involving elaboration sometimes make a generic package with
no parameters make sense.

If anyone could find a use for a generic subprogram with now parameters,
now that would be a trick!

doug
-------