comp.lang.ada
 help / color / mirror / Atom feed
From: "Robert I. Eachus" <rieachus@attbi.com>
Subject: Re: overriding "*", was Re: What's the ICFP Programming contest?
Date: Fri, 04 Jul 2003 07:01:55 GMT
Date: 2003-07-04T07:01:55+00:00	[thread overview]
Message-ID: <3F05265C.1010701@attbi.com> (raw)
In-Reply-To: 3F03E17E.7030305@attbi.com

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.




      reply	other threads:[~2003-07-04  7:01 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-06-26  1:30 What's the ICFP Programming contest? tmoran
2003-06-26  8:24 ` Preben Randhol
2003-06-27 20:37   ` Michael Erdmann
2003-06-28  0:21     ` tmoran
2003-06-28  7:33       ` Michael Erdmann
2003-06-29  6:47         ` Hyman Rosen
2003-06-29 22:37           ` tmoran
2003-07-01  5:58             ` overriding "*", was " tmoran
2003-07-01 20:52               ` Randy Brukardt
2003-07-02 17:10                 ` tmoran
2003-07-02 18:13                   ` Randy Brukardt
2003-07-03  7:55               ` Robert I. Eachus
2003-07-04  7:01                 ` Robert I. Eachus [this message]
replies disabled

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