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-29 11:16:39 PST Newsgroups: comp.lang.ada,comp.object,comp.lang.c++ Path: bga.com!news.sprintlink.net!howland.reston.ans.net!noc.near.net!inmet!spock!stt From: stt@spock.camb.inmet.com (Tucker Taft) Subject: Re: Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG) Message-ID: Keywords: Ada 9X, C++, object-oriented Sender: news@inmet.camb.inmet.com Organization: Intermetrics, Inc. References: <1994Sep27.165203.9192@swlvx2.msd.ray.com> <36bt0c$17oo@watnews1.watson.ibm.com> <1994Sep29.103358@di.epfl.ch> <36eebb$jn5@disunms.epfl.ch> Date: Thu, 29 Sep 1994 18:05:09 GMT Xref: bga.com comp.lang.ada:6307 comp.object:6891 comp.lang.c++:30979 Date: 1994-09-29T18:05:09+00:00 List-Id: In article <36eebb$jn5@disunms.epfl.ch>, Magnus Kempe wrote: > ... >The example below illustrates that Ada 9X allows you to easily model/ >implement abstractions and their relationships--while enforcing and >preserving the concomitant encapsulations. That's what I call progress! >(Yes, this all compiles with GNAT, a.k.a. "GNU Ada".) The type conversion toward the end of your example is illegal (at least according to *our* Ada 9X front end ;-). Remember GNAT is focusing on compiling correct programs first, and will eventually enforce all of the nit-picking RM rules, but for now, just because GNAT compiles something doesn't make it legal ... In any case, to me it is much simpler to declare abstract versions of Employee and Office in the same package, with appropriately mutually recursive (abstract) operations declared there as well. E.g.: package Company is type Office is abstract tagged null record; type Office_Pointer is access all Office'Class; type Employee is abstract tagged null record; type Employee_Pointer is access all Employee'Class; function Office_Occupied_By(The_Employee : Employee) return Office_Pointer is abstract; function Employee_Occupying (The_Office : Office) return Employee_Pointer is abstract; procedure Occupy (The_Office : in Office_Pointer; The_Employee : in Employee_Pointer); -- This one we presumably have to implement (though -- I'm not sure what the original author had in mind), -- perhaps by calling additional abstract primitive operations -- declared below.... ... end Company; You can then create concrete derivatives of these in separate packages, preserving complete encapsulation relative to one another (presuming that is a big deal). Few if any explicit conversions will be required with this approach. >Magnus Kempe "I know not what course others may take, but as for me, >Magnus.Kempe@di.epfl.ch Give me Liberty... or give me Death!" -- Patrick Henry -Tucker Taft stt@inmet.com Intermetrics, Inc. Cambridge, MA 02138 ------------------- P.S. FYI Here is the source code you suggested, with an indication of where the error occurs: > ... >package Company is >-- This subsystem exports two abstractions, Employee and Office, which >-- are mutually dependent (in a symmetric, one-to-one relationship). > >private >-- the following private declarations set up the 1-1 relationship > > ... [Eliding employee stuff] > > type Office_Parent; > type Office_Reference is access all Office_Parent'Class; > > ... [Eliding employee stuff] > > type Office_Parent is > abstract tagged > record > Its_Occupying_Employee : Employee_Reference; > end record; >end Company; > > ... [Eliding employee stuff] > >with ... ; -- other stuff needed by Office >package Company.Offices is > type Office is > private; > type Office_Pointer is > access all Office; > > No_Office : constant Office_Pointer := null; > ... -- Office subprograms involving that "other stuff" > >private > type Office is > new Office_Parent > with record > ... -- various components involving that "other stuff" > end record; >end Company.Offices; > > >-- we can now declare operations working with both abstractions >--------------------------------------------------------------- >with > Company.Employees, Company.Offices; >package Company.Common is > function Office_Occupied_By (The_Employee : in Employees.Employee) > return Offices.Office_Pointer; > > ... [Eliding employee stuff] >end Company.Common; > > ... [Eliding employee stuff] > >with Company.Employees.Ptrs; >package body Company.Common is > function Office_Occupied_By (The_Employee : in Employees.Employee) > return Offices.Office_Pointer is > begin > return Offices.Office_Pointer > (Employees.Ptrs.Office_of (The_Employee)); > -- the type conversion (from one access type to another) involves > -- a type check: is the designated object of type Offices.Office? > -- If not, exception Constraint_Error will be raised. ***** Here is the problem **** This type conversion is illegal, since at this point, it is not visible that Office is derived from Office_Parent. > end Office_Occupied_By; > ...