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;
next prev parent 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