From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,2ea02452876a15e1 X-Google-Attributes: gid103376,public From: ncohen@watson.ibm.com (Norman H. Cohen) Subject: Re: Choice of OO primitives in Ada95 Date: 1996/02/19 Message-ID: <4ga999$1bj2@watnews1.watson.ibm.com> X-Deja-AN: 140075848 distribution: world references: <4g2f8v$15lc@watnews1.watson.ibm.com> organization: IBM T.J. Watson Research Center reply-to: ncohen@watson.ibm.com newsgroups: comp.lang.ada Date: 1996-02-19T00:00:00+00:00 List-Id: In article , donh@syd.csa.com.au (Don Harrison) writes: |> I don't question the value of packages for non-OO encapsulation. I am interested |> to know what is the perceived flexibility wrt OO. Did Tucker meant flexibility |> wrt non-OO encapsulation? I can't speak for Tucker, but my argument is as follows: Packages, private parts, and package bodies are an appropriate mechanism for non-OO encapsulation that can be used in precisely the same way for OO encapsulation, equally appropriately. Therefore, a second, quite different mechanism for OO encapsulation would be redundant. |> :2. It allows data abstractions involving two or more intimately linked |> : types to be encapsulated together. For example: [my family-tree example deleted] |> |> This is an example of what I mean by tight-coupling of abstractions - you are |> forced to encapsulate both abstractions into a single module. No, I wasn't forced to do so, I chose to do so, because Marriage_Type and Person_Type are part of a single recursive data structure and the family-tree data abstraction has many operations that are most efficiently implemented by referring to both the Marriage_Type and Person_Type parts of this data structure. Other applications entail mutually dependent types that are not "initimately linked" in this way, and in such cases separate packages are more appropriate. A programmer whose encapsulation mechanism is a package has the freedom to choose whether or not the two types should be encapsulated together. A programmer whose encapsulation mechanism is the class does not. |> :|> As far as symmetry between operands is concerned, the benefits seem to be more |> :|> theoretical than practical. |> : |> :The ability to use natural notation has the very practical advantage of |> :making programs easier to read and understand. |> |> I would say the opposite is true - forcing a whole bunch of different abstractions |> into the one module creates an amorphous mess that the developer has to sift |> through to see which operations relate to which abstractions. This is a non sequitur. Your original remark about symmetry being of only theoretical interest referred to the ability to define truly symmetric binary dispatching operations. I replied that this ability provides a practical rather than theoretical advantage in terms of program understandability. You reply with a false and in any event irrelevant suggestion that packages "force" different abstractions into one module. |> An example might best illustrate what I mean. Extending your example and assuming |> each type is tagged, we might have: |> |> package X is |> type MARRIAGE is tagged ... |> type PERSON is tagged ... |> type UNIVERSITY is tagged ... |> type GOVERNMENT is tagged ... |> type ELECTORATE is tagged ... |> type ADDRESS is tagged ... |> |> procedure Enrol (Student : in out PERSON; Uni : in out UNIVERSITY); |> procedure Award_Grant (Polies : in out GOVERNMENT; Uni : in out UNIVERSITY); |> procedure Make_Gerrymander (Polies : in out GOVERNMENT; Elect : in out ELECTORATE); |> function Office_Address (Elect : in ELECTORATE) return ADDRESS; |> |> end X; |> |> Each abstraction is related to the previous one but isn't necessarily related |> to any other. As I understand it, the language rules dictate that each of these |> abstractions must be in the same package. You understand it incorrectly! |> But many of them have nothing to do with |> each other. They are tightly-coupled even though they should be distinct and this |> has been forced by the language rules. There are several solutions for writing data abstractions that have mutually dependent interfaces, but independent implementations, in separate packages. John Volan and I have debated two such approaches in this newsgroup ad nauseum. Ada packages give you the CHOICE of packaging two types together or separately. In the family-tree example, the two types are different aspects of the same abstraction, with a shared implementation, and a single package is appropriate. (Other examples: A package providing a type for linked lists and a type for cursors representing positions in linked lists; a package providing a type for points on a time line and a type for lengths of intervals on a time line; a package providing a type for machine addresses and a type for offsets between machine addresses; a package providing a type for sparse matrices, a type identifying a row of such a sparse matrix, and a type identifying a column of a sparse matrix; etc.) When it is not appropriate to package two mutually dependent types together, Ada packages give you the CHOICE to encapsulate them separately. -- Norman H. Cohen ncohen@watson.ibm.com