comp.lang.ada
 help / color / mirror / Atom feed
From: "Matthew Heaney" <mheaney@on2.com>
Subject: Re: Dimensions (was Re: Another Idea for Ada 20XX)
Date: Sat, 8 Dec 2001 13:59:56 -0500
Date: 2001-12-08T13:59:56-05:00	[thread overview]
Message-ID: <u14oi1linerke0@corp.supernews.com> (raw)
In-Reply-To: FxhQ7.15837$ER5.268492@rwcrnsc52


"Mark Lundquist" <mlundquist2@attbi.com> wrote in message
news:FxhQ7.15837$ER5.268492@rwcrnsc52...
>
> "Richard Riehle" <richard@adaworks.com> wrote in message
> news:3C118E95.B5F013C8@adaworks.com...
> > Mark Lundquist wrote:
> > >
> > > I have no idea what you're getting at with the "helper type to avoid
> > > recursion"... :-)
> >
> > In implementing the infix operators for an experimental version of this
> > package, I found myself having to solve the problem of having the
> > full definition of the type as a numeric type itself.
>
> Hmm, if I'm understanding this correctly, it's you always have this
problem
> when deriving privately and re-exporting the primitives of the base type
> (it's not unique to numeric types and/or infix operators).  You can always
> convert up to the base type and back down again in the body of the
> primitive, right?  Anyway, this is OT from our dimensions discussion,
> sorry...


This is an issue with the implementation of ADT's in Ada, that often trips
up the beginner.  It may seem perfectly reasonable to do this:

package P is
   type T is private;
   function "+" (L, R : T) return T;
private
   type T is new Integer;  --or whatever
end P;

package body P is
   function "+" (L, R : T) return T is
     Sum : T := L + R;  --oops
   begin
      if Sum > 100 then  --this type does "clamping"
        Sum := 100;
     end if;
    return Sum;
  end "+";
end P;

The problem is that with this type, externally you want "+" to have one
behavior, but internally you want "+" to have it's "normal" behavior.  But
in the implementation above, you have infinite recursion, because the
compiler doesn't make the same distinction you do.

There are a couple of ways to solve this problem.

I. Implement that ADT as a private derivation:

package P is
   type T is private;
   function "+" (L, R : T) return T;
private
   type T_Rep is new Integer;
   type T is new T_Rep;
end P;

Here is there is no problem, because the special "+" operation applies to T,
not T_Rep, so at least you now have a way to get back the "normal" behavior
of "+":

package body P is
   function "+" (L, R : T) return T is
     Sum : T_Rep := T_Rep (L) + T_Rep (R);
   begin
     if Sum > 100 then
       Sum := 100;
     end if;
     return T (Sum);
   end "+";
end P;

II. Implement the ADT as a record:

package P is
   type T is private;
   function "+" (L, R : T) return T;
private
   type T is record
      Rep : Integer;
   end record;
end P;

Now there is no comflict, because a record type doesn't already have a "+"
operator:

package body P is
   function "+" (L, R : T) return T is
      Sum : Integer := L.Rep + R.Rep;
   begin
      if Sum > 100 then
        Sum := 100;
      end if;
      return T'(Rep => Sum);
   end "+";
end P;

Ada83 probably would have been simpler had only records were allowed as
implementations of ADT's -- which is the case for Ada95 tagged types.  Oh
well, live and learn.

III.  For non-private ADT's

What I showed above (at least in I) applies when you have a private type
implemented as a scalar type.  If you don't need a private type, then you
have another option.  You're allowed to "squirral away" the predefined
operator, prior to overriding it:

package P is
   type T is new Integer;
   function Predefined_Add (L, R : T) return T renames "+";
   function "+" (L, R : T) return T;
end P;

Now you have an explicit way of getting back to the predefined operator:

package body P is
   function "+" (L, R : T) return T is
      Sum : T := Predefined_Add (L, R);
  begin
      if Sum > 100 then
        Sum := 100;
      end if;
      return Sum;
   end "+";
end P;








  reply	other threads:[~2001-12-08 18:59 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-12-02 19:51 Another Idea for Ada 20XX Gautier Write-only-address
2001-12-02 22:36 ` James Rogers
2001-12-03 12:44   ` Marc A. Criley
2001-12-03 14:29     ` Larry Kilgallen
2001-12-04  0:25       ` Marc A. Criley
2001-12-04  1:40   ` Adrian Hoe
2001-12-04  1:56     ` Larry Kilgallen
2001-12-04 16:08       ` Wes Groleau
2001-12-04 17:48         ` Larry Kilgallen
2001-12-09 23:02           ` Nick Roberts
2001-12-10 16:22             ` Stephen Leake
2001-12-10 17:11               ` Wes Groleau
2001-12-10 20:30               ` Robert C. Leif, Ph.D.
2001-12-10 20:59                 ` Wes Groleau
2001-12-10 17:09             ` Wes Groleau
2001-12-10 17:32               ` Larry Kilgallen
2001-12-04 19:59         ` Vincent Marciante
2001-12-04 20:20           ` Wes Groleau
2001-12-04 22:18         ` Matthew Heaney
2001-12-06  4:14         ` Richard Riehle
2001-12-06 17:39           ` Wes Groleau
2001-12-07  0:55             ` Adrian Hoe
2001-12-07  9:01               ` Dmitry A. Kazakov
2001-12-07 11:49           ` Tarjei T. Jensen
2001-12-07 22:51           ` Dimensions (was Re: Another Idea for Ada 20XX) Mark Lundquist
2001-12-08  3:52             ` Richard Riehle
2001-12-08  5:28               ` Mark Lundquist
2001-12-08 18:59                 ` Matthew Heaney [this message]
2001-12-08 21:23               ` Wes Groleau
2001-12-09 22:15               ` Robert C. Leif, Ph.D.
2001-12-10 14:09             ` Ian
2001-12-03 14:56 ` Another Idea for Ada 20XX Mark Lundquist
2001-12-06 15:27   ` Philip Anderson
2001-12-07 22:51     ` Mark Lundquist
2001-12-10  9:01       ` Dmitry A. Kazakov
replies disabled

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