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 -------