"Robert I. Eachus" <[log in to unmask]> writes: Thanks for the comments. I'll think some more about some of these things, I don't think my way is necessarily better, I'm just giving my rationale for the decisions I made. > > ( I'm sending this to you directly, but if you want to copy your reply > to TEAM-ADA, I have no problem with that.) I will. These are good comments. > > I've started to look at your components. What follows are a couple of > questions and comments. Much of this is questions of style, I'm not saying > what you did is wrong, I'm just feeling around for "more right." > > 1) Why is Limited_Object derived from Controlled, not Limited_Controlled? That's a mistake. Thanks for the info. > > 2) Why have the Baseclass package at all? There seems to be no > generality gained by not declaring these types in Asgc. Usually this > structure is chosen to avoid some elaboration order problems, but I don't > see any currently. The idea of Baseclass is not really for generality at that level. The Asgc object could have been its own tagged type and everything would have worked fine. However, after using Java for a while and doing work in object-based fault-tolerance, I find that it is quite convenient to have all classes in the system derive from one base class. That way containers of more general objects can be built, all objects can be treated the same at certain levels, etc. Also, making handling general interfaces (like Java, a special form of multiple inheritance) more general to be useful, too. So the expectation is the user would derive from Baseclass.Object, too, for their tagged types. So it is not required, but it seems to me to be more convenient. It's not that big a deal, though. > > 3) Personally, I would find it more appropriate to make the generic type > Object instead of Contained_Type, and to have the container classes derive > from a root type Container: > > type List is new Container with private; > ... > (and in asgc.lists.fixed:) > type Fixed_List is new List with private; > > 4) My style for doing this would be to have a single non-generic parent > package, each of the types of container as a non-generic child, and finally > the "real" packages as generic grandchildren with the Contained_Type > (renamed ;-) as a generic parameter. I wanted to push generality as far down the package hierarchy as I could. So, for instance, you can take any container and search it, get values from it, etc. Without the genericity pushed all the way down the package hierarchy, that was not possible except for a very limited set of operations. Making things as general as possible as far down the package hierarchy as possible allows the most allows the most flexibility for replacing containers, too. If for instance, I am using a fixed doubly linked list and later on I determine that I need a dynamic list, or that I need to use an array-based list (AList), etc. I can instantiate the variable with a different package in one place (if the variable is as generic as possible) and the job is done. There are other useful ways to accomplish this, too, such as renaming the packages you want and then working with those package names exclusively. My examples currently don't do this, I probably need to add some that do and add some documentation that this is my intent. The test routines do take advantage of this. For instance, there is one routine to test graphs, but nine different types of graphs. The routine takes a generic graph baseclass and does the tests, it gets called with nine different types of graphs. The main disadvantage I have seen so far is that lots of package instantiation has to be done. It's kind of a pain, but I don't think it contributes much to executable bloat because all but the "leaf" packages tend to be very abstract and quite small. > > 5) You have many different access types named Object_Class. This > creates a painful confusion if you use more than one container type in a > program. It would be nice to have Container_Class, List_Class, > Fixed_List_Class, etc. Better might be to name them _Pointer, or _Handle, > but that is a different discussion. I have quit following that discussion :-). _Handle might be a better name, but I really wanted to convey that fact that is is class-wide. (I use _Ptr for things that are not class-wide). Anyway, I believe that having everything as an Object and Object_Class makes things less confusing, not more. I don't like to "use" packages unless they are very familiar, I like to rename them to what I want and use that name throughout. So for the the containers, you might take a doubly linked list (DList) and use it as a queue. You would rename or instantiate the DList package you wanted to be a Queue package, but wouldn't "use" the Queue package. Then you would say something like: package Integer_Base is new Asgc(Contained_Type => Integer); package Integer_Queue is new Integer_Base.Ordered; package Integer_Queue_DList is new Integer_Queue.DList; package Integer_Dynamic_Queue_DList is new Integer_Queue_Dlist.Fixed; Then later on, instantiate it with: My_Queue : Integer_Queue.Object_Class := new Integer_Dynamic_Queue_Dlist.Object; Then I would use the methods defined in Integer_Queue to operate on the queue. If it was done the way you suggest, you would end up saying: My_Queue : Integer_Queue.Dynamic_DList_Ptr := new Integer_Queue.Dynamic_DList; which I don't like as much, personally. However, as threads on comp.lang.ada show, there are quite a few opinions on this :-). -- Corey Minyard Internet: [log in to unmask] Work: [log in to unmask] UUCP: [log in to unmask]