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 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,CP1252 X-Google-Thread: 103376,dab1e23fc81e6b17 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2003-07-04 00:01:58 PST Path: archiver1.google.com!news1.google.com!newsfeed.stanford.edu!logbridge.uoregon.edu!newshub.sdsu.edu!elnk-pas-nf2!newsfeed.earthlink.net!wn14feed!wn13feed!wn12feed!worldnet.att.net!204.127.198.203!attbi_feed3!attbi_feed4!attbi.com!sccrnsc02.POSTED!not-for-mail Message-ID: <3F05265C.1010701@attbi.com> From: "Robert I. Eachus" User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) Gecko/20021120 Netscape/7.01 X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: overriding "*", was Re: What's the ICFP Programming contest? References: <3F03E17E.7030305@attbi.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 8bit NNTP-Posting-Host: 24.62.164.137 X-Complaints-To: abuse@attbi.com X-Trace: sccrnsc02 1057302114 24.62.164.137 (Fri, 04 Jul 2003 07:01:54 GMT) NNTP-Posting-Date: Fri, 04 Jul 2003 07:01:54 GMT Organization: AT&T Broadband Date: Fri, 04 Jul 2003 07:01:55 GMT Xref: archiver1.google.com comp.lang.ada:40046 Date: 2003-07-04T07:01:55+00:00 List-Id: Robert I. Eachus wrote: I said: > There are fixed-point multiplying operators that return universal-fixed. > You can't override or hide them. What you can do is write: > > C := Numbers'(A * B); > > This requires the result to be of type Numbers. The magic is that in > Ada 95, there can be an implict conversion on the assignment, but the > qualified expression comes first. But I just tried this example on GNAT: procedure Fixed_Example is type Root_Numbers is delta 0.0625 range -1000.0..1000.0; type Numbers is new Root_Numbers; function "*"(Left, Right : Numbers) return Numbers is begin return Numbers(Integer(Left/Numbers'Small)* Integer(Right/Numbers'Small)*Numbers'Small); end "*"; A, B, C : Numbers := 42.0; begin C := Numbers'(A * B); end Fixed_Example; And got a nasty message. This is definitely a bug, but I don't think it is a compiler bug, it is a language bug. As I remember it, Tuck, Ben Brosgol, Dave Emery?, myself and one or two others discussed this at a meeting at Wellesley College. (Robert Dewar was there, but I think he was in another meeting when this was discussed.) In any case, the intention was that the implicit conversions should only occur in certain contexts, including parameters and assignment statements but not type conversions and qualified expressions to deal with just this issue. There is/was an AI on the issue, AI-193. The result, approved by WG9 was to take no action. That probably should be reconsidered for Ada 2005, but that doesn't mean it will change. However, writing in 1996, I had a solution, I just didn't remember it correctly: ======================================================================== !section 4.5.5(18) !subject User-defined fixed,fixed multiplying op !reference RM95-4.5.5(18-20) !reference RM95-3.1.4(6-8) !reference RM95-3.2.3(1) !reference RM95-A.1(34-35) !reference 1996-5700.a Tucker Taft 1996-9-17 !reference 1996-5707.a Robert Dewar 1996-9-26 !reference AI95-00163/00 !from Robert Eachus 1996-10-14 !keywords incompatibility, fixed point, user-defined operator !reference 96-5727.a Robert I. Eachus 96-10-14>> !discussion ... Finally, the trick that started me writing this. If you want to write expressions using user defined multiplying operations for fixed point types, it is possible. You can even do it in the C := A*B format. But literals require explicit user-defined conversions. (Which do nothing in the object code, but can look messy in the source, and you get wierd error messages if you leave out a "+".) package My_Fixed is type Real_Fixed is delta ...; type Fixed is private; function "+" (L,R: Fixed) return Fixed; ... function "/" (L,R: Fixed) return Fixed; private type Fixed is new Real_Fixed; end My_Fixed; If you add in the "standard" conversion operations: function "+"(L: in Real_Fixed) return Fixed; and function "-"(L: in Real_Fixed) return Fixed; Then the only "penalties" incurred outside the package are that literals have to have signs, and that you can't instantiate generics that require fixed point types on Fixed. But you don't want to do that (other than for Text_IO.Fixed_IO). You want generics which have generic formal subprograms to match the operators, or you want generic formal derived types. So make My_Fixed itself a generic package (with a Fixed_IO child), and use generic formal package types. The final result looks like: generic type Real_Type is delta <>; package Special_Fixed is type Fixed is private; function "+"(L: in Real_Type) return Fixed; function "-"(L: in Real_Type) return Fixed; function "+" (L: Fixed) return Fixed; function "-" (L: Fixed) return Fixed; function "+" (L,R: Fixed) return Fixed; ... function "/" (L,R: Fixed) return Fixed; private type Fixed is new Real_Type; pragma Inline(...); end Special_Fixed; with Text_IO; generic package Special_Fixed.Fixed_IO is ... end Special_Fixed.Fixed_IO; If NASA, or whoever, isn't happy with this, they can contact their vendor. ========================================================================== So there is the workaround, but I think for Ada 2005 we need a better solution. I personally think that implicit conversions in a qualified expression are evil in general, and fixing that would certainly help in this case. -- Robert I. Eachus �In an ally, considerations of house, clan, planet, race are insignificant beside two prime questions, which are: 1. Can he shoot? 2. Will he aim at your enemy?� -- from the Laiden novels by Sharon Lee and Steve Miller.