comp.lang.ada
 help / color / mirror / Atom feed
From: John Volan <johnv@ac3i.dseg.ti.com>
Subject: Re: Mutually dependent private types
Date: 1998/05/22
Date: 1998-05-22T00:00:00+00:00	[thread overview]
Message-ID: <3565B105.9BFB4788@ac3i.dseg.ti.com> (raw)
In-Reply-To: matthew_heaney-ya023680002105982333070001@news.ni.net


Matthew Heaney wrote:
> 
> 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.

Adam's two types didn't need to know about each other's implementations.
Even if you had the P1.T1 type holding a reference (access) to a P2.T2
object, from the perspective of package P1, P2.T2 could still look like
a private type.  And vice versa in the other direction.

> 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.

See http://bluemarble.net/~jvolan/WithingProblem/FAQ.html#strong_typing,
where I describe how the with-ing problem can be avoided, at the expense
of Ada95's static strong typing checks, by deriving all your object
classes from some universal root type (Objects.Object_Type was my
suggestion).  

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

Yes, but unfortunately it forces Ada95 to act a lot like Smalltalk. The
programmer presumably knows statically that O1 is always supposed to be
a T1 and O2 is always supposed to be a T2, but this coding style
prevents the compiler from knowing that.  It is very possible that
someone could write code that tried to pass something other than a T2
into P1.Op1. Such code would of course be a bug, but it wouldn't be
caught until the call to P1.Op1 was actually executed and the tag-check
was performed.  Depending on the testing scheme used during development,
this call may or may not get executed.  So this bug could actually go
undetected during testing and wind up being reported by an irate end
user.

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

[snip Matt's example]

The *_Rep types aren't even necessary, if you're going to go with the
universal root type strategy:

package Adam is
   type Root is abstract tagged null record;
end Adam;

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

   function Get_F (O1 : in T1) return Float;

private

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

end Adam.P1;

with Adam.P2;
package body Adam.P1 is

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

   function Get_F (O1 : in T1) return Float is
   begin
      return O1.F;
   end Get_F;

end Adam.P1;

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

   function Get_I (O2 : in T2) return Integer;

private

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

end Adam.P2;

with Adam.P1;
package body Adam.P2 is

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

   function Get_I (O2 : in T2) return Integer is
   begin
      return O2.I;
   end Get_I;

end Adam.P2;

with Adam.P1;
with Adam.P2;

procedure Adam.Test is

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

begin

   P1.Op1 (O1, O2);
   P2.Op2 (O2, O1);

end Adam.Test;

-- 
Signature volanSignature = 
  new Signature
  ( /*name:      */ "John G. Volan",
    /*employer:  */ "Raytheon Advanced C3I Systems, San Jose",
    /*workEmail: */ "johnv@ac3i.dseg.ti.com",
    /*homeEmail: */ "johnvolan@sprintmail.com",
    /*selfPlug:  */ "Sun Certified Java Programmer",
    /*twoCents:  */ "Java would be even cooler with Ada95's " +
                    "generics, enumerated types, function types, " +
                    "named parameter passing, etc...",
    /*disclaimer:*/ "These views not packaged in COM.ti.dseg.ac3i, " +
                    "so loading them throws DontQuoteMeError. :-)" );




  reply	other threads:[~1998-05-22  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 ` John Volan
1998-05-21  0:00 ` Matthew Heaney
1998-05-22  0:00   ` John Volan [this message]
1998-05-22  0:00     ` Matthew Heaney
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-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
  -- strict thread matches above, loose matches on Subject: below --
1998-05-22  0:00 adam
1998-05-22  0:00 ` Brian Rogoff
1998-05-22  0:00 ` Matthew Heaney
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