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.8 required=5.0 tests=BAYES_00,INVALID_DATE autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 109fba,66253344eaef63db X-Google-Attributes: gid109fba,public X-Google-Thread: 1108a1,66253344eaef63db X-Google-Attributes: gid1108a1,public X-Google-Thread: 103376,66253344eaef63db X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 1994-09-28 19:28:37 PST Newsgroups: comp.lang.ada,comp.object,comp.lang.c++ Path: bga.com!news.sprintlink.net!howland.reston.ans.net!swrinde!ihnp4.ucsd.edu!dog.ee.lbl.gov!overload.lbl.gov!lll-winken.llnl.gov!noc.near.net!ray.com!news.ray.com!news.ed.ray.com!swlvx2!jgv From: jgv@swl.msd.ray.com (John Volan) Subject: Re: Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG) Date: Thu, 29 Sep 1994 01:46:11 GMT Message-ID: <1994Sep29.014611.20263@swlvx2.msd.ray.com> References: <1994Sep27.165203.9192@swlvx2.msd.ray.com> <1994Sep27.184827.17813@wdl.loral.com> Sender: news@swlvx2.msd.ray.com (NEWS USER) Keywords: Ada 9X, C++, object-oriented Organization: Raytheon Company, Tewksbury, MA Xref: bga.com comp.lang.ada:6279 comp.object:6875 comp.lang.c++:30871 Date: 1994-09-29T01:46:11+00:00 List-Id: Mark, Thanks for your suggestion, but I think there are some problems with it: MAB = mab@dst17.wdl.loral.com (Mark A Biggar) writes: MAB>[Discussion of how to set up mutualy recursive tagged types] MAB> MAB>First of all you really only need to have a forward definition of one MAB>of the two types, lets choose office. Okay, I can buy that. I'd like to keep things symmetrical if possible, but I can live without it if I have to ... MAB>So first define a abstract office type that doesn't knoe about employees: MAB> MAB> package Abs_Office is MAB> MAB> type Abstract_Office is abstract tagged null record; MAB> type Access_Office is access all Abstract_Office'class; MAB> MAB> end Abs_Office; Hmmm... So, from this "abstract" point of view, an Office has no features whatsoever. No components or subprograms (whether publicly or privately visible) that deal with the fact that an Office will point to an Employee, nor even any of the "other stuff" that makes up an Office. (Perhaps you're leaving it open where that "other stuff" could go, but for now I'm going to take what you've written above at face value). Actually, I wouldn't call this an "abstract" view of an Office. Rather, let me define this as an abstract *class* that provides an "opaque" *view* of an Office. MAB>Now we can define the employee type in terms of the above abstract type: MAB> MAB> with Abs_Office; use Abs_Office; MAB> package Emp is MAB> MAB> type Employee is tagged record MAB> Office: Access_Office; MAB> end record; MAB> type Employee_Access is access all Employee'class; MAB> MAB> end Emp; ... I'm going to assume that this Employee type would really have a lot of "other stuff" in it along with this pointer, and that this package spec would also include all the primitive subprograms that define the Employee class, including subprograms that deal with the "other stuff" as well as the association with Office. The trouble here is that even though an Employee now has a pointer to an Office, this pointer only gives the Employee an "opaque" view of an Office. The "public" view of an Office is eventually going to be supplied via a *subclass* of this "opaque" view -- but the Employee class doesn't have access to that "public" view. Although I didn't explicitly say so in my original post, I'm assuming that the Employee class might very well be a full client of the Office class (and vice versa). This means that the bodies of all Employee subprograms ought to have full visibility to the public subprograms of the Office class. But even if Employee isn't *itself* a client of Office, we certainly can assume that the *clients* of Employee *will* be clients of Office as well! Let's say some client of Employee asks an Employee object for its Office. The Employee object will give back one of these "opaque" pointers in response. What can the client do with that pointer? As far as it can see, the Office object being pointed to is totally featureless. Oh, sure, it's possible that this Office object is really some subclass of Abstract_Office that does have useful features, but this information isn't available to the client. The only way the client could get to that information would be to use an unchecked conversion to change this "opaque" pointer into a pointer to the "non-opaque" Office subclass below. (I think folks in the other languages would call this "downcasting".) But this practice breaks type-safety! (Okay, maybe we could endow the abstract class with all the "other stuff", rather than wait until the subclass below. That way, a client would at least have visibility to that "other stuff". But my feeling is that the Office's association with the Employee is just as important a feature as the "other stuff". Maybe the client would want to ask the Office for its associated Employee again later, for some reason. Or maybe a client might want to tell the Office to *change* its Employee--i.e., tell the old one to vamoose and let some new guy occupy the Office! :-) MAB>Now we can define the real office type: MAB> MAB> with Abs_Office; use Abs_Office; MAB> with Emp; use Emp; MAB> package Off is MAB> MAB> type Office is new Abstract_Office with record MAB> Employee: Employee_Access; MAB> end record; MAB> MAB> end Off; At least the full Office class gets visibility to the public interface of the Employee class. But not vice versa. MAB>This of course ignores the private aspects of the C++ example given in the MAB>original article, but these are easly added using private types and/or MAB>private extensions in the above packages. MAB> MAB>Moral: if you need mutualy recursive tagged types with out breaking MAB>encapsulation, then use an abstract type for you forward reference. Moral: An "opaque" abstract class might preserve encapsulation, but it doesn't provide true mutual recursion. MAB> MAB>-- MAB>Mark Biggar MAB>mab@wdl.loral.com -- John Volan -------------------------------------------------------------------------------- -- Me : Person := (Name => "John Volan", -- Company => "Raytheon Missile Systems Division", -- E_Mail_Address => "jgv@swl.msd.ray.com", -- Affiliation => "Enthusiastic member of Team Ada!", -- Humorous_Disclaimer => "These opinions are undefined " & -- "by my employer and therefore " & -- "any use of them would be " & -- "totally erroneous."); --------------------------------------------------------------------------------