comp.lang.ada
 help / color / mirror / Atom feed
From: matthew_heaney@acm.org (Matthew Heaney)
Subject: Re: Mutually dependent private types
Date: 1998/05/21
Date: 1998-05-21T00:00:00+00:00	[thread overview]
Message-ID: <matthew_heaney-ya023680002105982333070001@news.ni.net> (raw)
In-Reply-To: 6k25ra$6j7$1@nnrp1.dejanews.com


In article <6k25ra$6j7$1@nnrp1.dejanews.com>, adam@irvine.com wrote:

(start of quote)
I've run into another problem trying to get something implemented in
Ada 95.  This problem seems superficially similar to John Volan's
with-ing problem, but I don't think it's quite the same.

(1) If I want to have two private types in two separate packages whose
    *implementations* are mutually dependent on each other, this is
    easy to do, if we're willing to make the private types accesses:
(end of quote)

Done.

(start of quote)
(2) Another mutual-dependency situation is this: Suppose I want to
    have two types T1 and T2 in two different packages, and I want to
    provide operations on T1 that take T2 as a parameter, and
    operations on T2 that take T1 as a parameter.  You can't do this
    by declaring T1 and T1's operations in the same package and do the
    same for T2, since then the two package specs would have to be
    mutually dependent.  However, you can solve this problem by
    separating the type definition from the operations in two separate
    packages (preferably using child units):
(end of quote)

Done.

(start of quote)
(3) But what happens if you want to do both (1) and (2)?  Now the
    whole thing seems to break down.  If you try to do both of the
    above, something like:
(end of quote)

Done.

Here's is a solution to your problem.  

1) No private child package is required.  Move the representation of T1 and
T2 up into the private region of a common parent package.

2) Types T1 and T2 privately derive from the respective rep types.  Each
type, because it's in a child package of package containing both rep types,
has direct visibility to the rep of the other type.

3) The mutual dependency in operations is effected by making the other type
have type Root'Class, in the spec.  In the body, just downcast the object
to the representation type.  Of course, the compiler can't verify
statically that the object is really of the required type, but you'll find
out at runtime, because a tag check happens when you downcast.

This is out-of-the-box Ada 95.  No complex language extensions or
Unchecked_Conversion or implementing types using access types is required.

I read John's paper, but I don't find his argument convincing.  Doesn't the
following code solve the putative with'ing "problem"?

Matt


--STX
package body Adam.P1 is

   procedure Op1 (O1 : in out T1; O2 : in Root'Class) is
   begin
      O1.F := Float (T2_Rep (O2).I);
   end Op1;

end Adam.P1;
package Adam.P1 is

   type T1 is new Root with private;

   procedure Op1 (O1 : in out T1; O2 : in Root'Class);
   -- precondition: O2 in P2.T2'Class

private

   type T1 is new T1_Rep with null record;

end Adam.P1;
package body Adam.P2 is

   procedure Op2 (O2 : in out T2; O1 : in Root'Class) is
   begin
      O2.I := Integer (T1_Rep (O1).F);
   end Op2;

end Adam.P2;
package Adam.P2 is

   type T2 is new Root with private;

   procedure Op2 (O2 : in out T2; O1 : in Root'Class);
   -- precondition: O1 in P1.T1'Class

private

   type T2 is new T2_Rep with null record;

end;
with Adam.P1;
with Adam.P2;

procedure Adam.Test is

   O1 : P1.T1;
   O2 : P2.T2;

   use P1, P2;

begin

   Op1 (O1, O2);
   Op2 (O2, O1);

end Adam.Test;

package Adam is

   pragma Pure; -- the package, not Adam!

   type Root is abstract tagged null record;

private

   type T1_Rep is
     new Root with record
        F : Float;
     end record;


   type T2_Rep is
     new Root with record
        I : Integer;
     end record;

end Adam;




  reply	other threads:[~1998-05-21  0:00 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-05-21  0:00 Mutually dependent private types adam
1998-05-21  0:00 ` Matthew Heaney [this message]
1998-05-22  0:00   ` John Volan
1998-05-22  0:00     ` Matthew Heaney
1998-05-26  0:00       ` John Volan
1998-05-26  0:00         ` Matthew Heaney
1998-05-27  0:00           ` John Volan
1998-05-27  0:00             ` Matthew Heaney
1998-05-28  0:00               ` John Volan
1998-05-28  0:00                 ` Matthew Heaney
1998-05-29  0:00                   ` John Volan
1998-05-29  0:00                 ` Brian Rogoff
1998-05-29  0:00                   ` John Volan
1998-05-29  0:00                     ` Brian Rogoff
1998-05-29  0:00                       ` John Volan
1998-05-30  0:00                 ` Geoff Bull
1998-05-30  0:00                   ` Fergus Henderson
1998-06-01  0:00                     ` John Volan
1998-06-02  0:00                       ` Fergus Henderson
1998-06-04  0:00                       ` Robert Dewar
1998-05-26  0:00       ` Robert I. Eachus
1998-05-26  0:00         ` John Volan
1998-05-27  0:00           ` Robert I. Eachus
1998-05-29  0:00             ` John Volan
1998-05-27  0:00           ` Jerry van Dijk
1998-05-29  0:00             ` John Volan
1998-05-21  0:00 ` John Volan
  -- strict thread matches above, loose matches on Subject: below --
1998-05-22  0:00 adam
1998-05-22  0:00 ` Matthew Heaney
1998-05-22  0:00 ` Brian Rogoff
1998-05-22  0:00 ` 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