comp.lang.ada
 help / color / mirror / Atom feed
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
Date: 1994-09-29T01:46:11+00:00	[thread overview]
Message-ID: <1994Sep29.014611.20263@swlvx2.msd.ray.com> (raw)
In-Reply-To: 1994Sep27.184827.17813@wdl.loral.com

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.");
--------------------------------------------------------------------------------








  reply	other threads:[~1994-09-29  1:46 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1994-09-27 16:52 Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG) John Volan
1994-09-27 18:48 ` Mark A Biggar
1994-09-29  1:46   ` John Volan [this message]
1994-09-29 13:57     ` Tucker Taft
1994-09-29 17:20       ` Bjarne Stroustrup <9758-26353> 0112760
1994-09-30  1:38         ` Tucker Taft
1994-09-30 12:33           ` Bjarne Stroustrup <9758-26353> 0112760
1994-09-29 18:37       ` John Volan
1994-09-29 19:34         ` David Weller
1994-09-30 22:13           ` John Volan
1994-10-02  3:31             ` Andrew Lees
1994-09-30  1:47         ` Tucker Taft
1994-09-30 13:30           ` John Volan
1994-09-29 18:10     ` R. William Beckwith
1994-10-03  0:33     ` Cyrille Comar
1994-09-28 14:01 ` Norman H. Cohen
1994-09-29  2:12   ` John Volan
1994-09-29 14:01     ` Tucker Taft
1994-09-29 18:37     ` Norman H. Cohen
1994-09-29  9:48   ` Magnus Kempe
1994-09-29 13:10     ` Magnus Kempe
1994-09-29 18:05       ` Tucker Taft
1994-09-30 10:20         ` Mut. Recurs. in Ada9X w/o Breaking Encaps.? Magnus Kempe
1994-09-30 13:22           ` Tucker Taft
1994-10-01  1:24       ` Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG) Adam Beneschan
1994-10-01 12:01         ` Magnus Kempe
1994-10-01 18:43         ` Mark A Biggar
1994-10-02 16:41         ` John Volan
1994-10-02 23:33           ` Matt Kennel
1994-10-03  8:07           ` Mut. Recurs. in Ada9X w/o Breaking Encaps.? Magnus Kempe
1994-10-03 12:14           ` Mut. Recurs. in Ada9X w/o Breaking Encaps.? (LONG) Robert I. Eachus
1994-10-04  2:12             ` R. William Beckwith
1994-10-04 16:00             ` John Volan
1994-10-05 11:42               ` Robert I. Eachus
1994-10-05 21:09               ` Matt Kennel
1994-10-03 20:29           ` Harry Koehnemann
1994-09-29 13:35     ` John Volan
1994-09-30 20:27       ` Norman H. Cohen
1994-10-01  1:47         ` John Volan
1994-10-01 20:44           ` Tucker Taft
1994-10-03 11:29           ` Robert I. Eachus
1994-09-30 22:46       ` Matt Kennel
1994-10-01  2:11         ` John Volan
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox