From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,LOTS_OF_MONEY, T_FILL_THIS_FORM_SHORT autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,cc4f25d878383cc X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-12-08 10:56:08 PST Path: archiver1.google.com!news1.google.com!sn-xit-02!sn-post-01!supernews.com!corp.supernews.com!not-for-mail From: "Matthew Heaney" Newsgroups: comp.lang.ada Subject: Re: Dimensions (was Re: Another Idea for Ada 20XX) Date: Sat, 8 Dec 2001 13:59:56 -0500 Organization: Posted via Supernews, http://www.supernews.com Message-ID: References: <3C0AACCE.329CFB60@worldnet.att.net> <45601fc.0112031740.3e217c8a@posting.google.com> <3C0CF4E3.A53D20A7@sparc01.ftw.rsc.raytheon.com> <3C0EF0A0.9F42EDB4@adaworks.com> <7KbQ7.13821$L51.28784@rwcrnsc54> <3C118E95.B5F013C8@adaworks.com> X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4807.1700 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4807.1700 X-Complaints-To: newsabuse@supernews.com Xref: archiver1.google.com comp.lang.ada:17629 Date: 2001-12-08T13:59:56-05:00 List-Id: "Mark Lundquist" wrote in message news:FxhQ7.15837$ER5.268492@rwcrnsc52... > > "Richard Riehle" 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;