Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!ncrlnk!ncrcae!hubcap!billwolf%hazel.cs.clemson.edu From: billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe,2847,) Newsgroups: comp.sw.components Subject: Re: Inheritance vs. component efficienc Message-ID: <5783@hubcap.clemson.edu> Date: 16 Jun 89 02:06:16 GMT References: <5044@wiley.UUCP> Sender: news@hubcap.clemson.edu Reply-To: billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu Lines: 78 From article <5044@wiley.UUCP>, by simpson@trwarcadia.uucp (Scott Simpson): > I assume you mean you wish to incrementally wrap packages in this manner. > If this is the case, you have to create new functions that are in > one-to-one correspondence with the package at the previous level. This > is error prone. Also, you will have to *add code* to handle the added > state. In an OOPL neither do you repeat operations nor add code. > You simply specify the relationship that one type is a subtype of another. > This relationship is language enforced and language supported. It is not > by convention. > >> when you wish to add a layer of abstraction; simply have a program ask you >> for the name of the new data type(s) and automatically generate a higher- >> level package which implements itself through calls to the lower-level >> packages. Q.E.D., as they say in mathematics... > > Writing such a program is not necessary in an OOPL. How will this > automatic code generation program know how to write code for the added > state? Do you know of such a program? Incremental wrapping can be accomplished automatically, and can also serve to map a single new abstraction to N underlying abstractions. The basic approach is to specify to the program the underlying type(s) and the name of the new type you wish to create. The program analyzes the files containing the specifications of the underlying ADTs and creates a new specification containing the new type name and all the operations applicable to the underlying ADTs, eliminating duplicates. Next, the program creates the package body. The type is automatically implemented: package body New_Type_ADT is -- type New_Type is limited private; -- type New_Type_Descriptor; -- type New_Type is access New_Type_Descriptor; type New_Type_Descriptor is record Underlying_Type_A : First_Underlying_Type; Underlying_Type_B : Second_Underlying_Type; -- etc. end record; procedure New_Type_Operation_X (The_New_Type : in out New_Type) is -- Let's assume that this is an operation applying to -- both underlying types; then we call the underlying -- packages to update the state of both fields... begin -- New_Type_Operation_X First_Underlying_Type_ADT.New_Type_Operation (New_Type.Underlying_Type_A); Second_Underlying_Type_ADT.New_Type_Operation (New_Type.Underlying_Type_B); end New_Type_Operation_X; -- etc. for other operations, as appropriate... end New_Type_ADT; Now you can go in and add new states, make changes, etc. as necessary. Each procedure can be recoded as necessary, while the default of just calling an underlying abstraction is available in case you wish to employ it. We can still replace the implementation at any time without recompiling anything depending upon the specification. We retain total control of every detail of the implementation; if it is not appropriate to update all N subcomponents in the example above, then it's easy to just edit the implementation to suit your needs. In short, I consider the problem to be simply a question of tool availability, similar to the problem of automatically generating the compilable outline of a package body from the package's specification. In what way does this not satisfy all requirements? Bill Wolfe, wtwolfe@hubcap.clemson.edu