Version 1.1 of ai05s/ai05-0123-1.txt

Unformatted version of ai05s/ai05-0123-1.txt version 1.1
Other versions for file ai05s/ai05-0123-1.txt

!standard 4.5.2(10-26)          08-10-18 AI05-0123-1/01
!class Amendment 08-10-17
!status work item 08-10-17
!status received 08-09-03
!priority Low
!difficulty Hard
!subject Composibility of equality
!summary
** TBD **
!problem
Consider the following example
type My_Float is new Float; function "=" (L, R : My_Float) return Boolean is begin if L > 0.99 * R and then L < 1.01 * R then return True; -- Near enough else return False; end if; end "=";
type Position is record Latitude : My_Float; Longitude : My_Float; end record;
Position1 : Position := (90.00, 90.00); Position2 : Position := (90.01, 89.99);
begin if Position1 = Position2 then –- Uses original predefined equals -- for components
The user might expect that the type Position would use the newly defined equality for its components. However, predefined equality reemerges unless the type is tagged. The user therefore has to remember to redefine equality for the type Position as well. This is a potential source of errors and confusion.
!proposal
Introduce a pragma Composable_Equality(Type_Name) to indicate that the same composability rules that apply to tagged types also apply to the type Type_Name.
!wording
** TBD **
!discussion
The fact that all types do not compose for equality is surprising. However, although it was changed for tagged types when they were introduced in Ada 95, it was not done for nontagged types for reasons of backward compatibility.
One possible workaround is to declare the types to be tagged but this is not always appropriate.
[Editor's commentary: It seems to me that the rationale here is poorly thought out, especially considering that the effects on generics are not considered. (See Pascal Leroy's note below for a discussion of some of them.)
In any case, a solution to this problem was considered for Ada 2005 (see AI95-00304-1). It was limited to untagged records to avoid running into problems with generics (like the ones noted by Pascal).
For that, a pragma solution was avoided because it would violate Bob Duff's Rule of Good Taste in Pragmas, which is, "Pragmas should not have a strong effect on high-level semantics."
A syntactic solution like the one proposed in that AI are annoying, because they're almost always what you want (and omitting it when it was intended would cause bad results that would be very hard to find).
Eventually, this was considered just not important enough for the work needed (even though it was not much in the case of this proposal).
I have to wonder what has changed.]
!example
** TBD **
!ACATS test
** TBD **
!appendix

From: John Barnes
Sent: Wednesday, September 3, 2008  1:47 AM

I have a request from members of the BSI Ada panel to consider the attached
thoughts on composability of equality.

Can we put it on the agenda for the next meeting please?


!standard                                           08-09-03 AI05-nnnnn-1/01
!class Amendment
!status work item
!status received
!priority Medium
!difficulty Easy
!subject Composability of equality

!summary

A pragma Composable_Equality is proposed to indicate that equality for the type
is to be composable.

!problem

Consider the following example

type My_Float is new Float;
   function "=" (L, R : My_Float) return Boolean is
   begin
     if L > 0.99 * R and then L < 1.01 * R then
       return True; -- Near enough
     else
       return False;
     end if;
   end "=";

   type Position is
   record
     Latitude  : My_Float;
     Longitude : My_Float;
   end record;

   Position1 : Position := (90.00, 90.00);
   Position2 : Position := (90.01, 89.99);

 begin
   if Position1 = Position2 then –-  Uses original predefined equals
                                 --  for components

The user might expect that the type Position would use the newly defined
equality for its components. However, predefined equality reemerges unless
the type is tagged. The user therefore has to remember to redefine equality
for the type Position as well. This is a potential source of errors and
confusion.


!proposal

Introduce a pragma Composable_Equality(Type_Name) to indicate that the
same composability rules that apply to tagged types also apply to the type
Type_Name.

!wording

tbd

!discussion

The fact that all types do not compose for equality is surprising.
However, although it was changed for tagged types when they were introduced
in Ada 95, it was not done for nontagged types for reasons of backward
compatibility.

One possible workaround is to declare the types to be tagged but this is
not always appropriate.

Are there similar problems with user-defined operations in generics
and what should be done about it?

!example

!ACATS test

!appendix

****************************************************************

From: Robert Dewar
Sent: Wednesday, September 3, 2008  9:09 AM

Can we have a reminder of the rationale behind NOT making this
commposable in the first place?

****************************************************************

From: Robert Dewar
Sent: Wednesday, September 3, 2008  9:09 AM

I would also allow this as a configuration pragma without a type name,
meaning that it applies to all types (really quite a language change,
but that's really the intent here).

****************************************************************

From: Pascal Leroy
Sent: Friday, September 5, 2008  12:36 AM

I find the idea of so-called composable equality for elementary types
(especially for floats, as shown in the example) extremely dangerous.
There is no way that the behaviour of any generic (notably the ones
in Ada.Numerics) can be predicted.  I am pretty sure that the IBM
implementation of the elementary functions and the matrix algorithms
would fall over dead with the "=" shown in the example (or at least
return random results -- think of the computation of eigenvalues as
an example).  Furthermore, many of these generics expect some
consistency between "=" and the other relational operators.
Presumably redefining "=" doesn't affect "<=", which is unlikely
to be what the author of the generic intended.

Overall, I think the proposal only makes sense for (untagged) records.
And I am not too excited by the prospect of a configuration pragma:
it seems to me that users should give careful thought to the impact
of using this pragma, they should not just slap it in the configuration
and forget about it.

Incidentally, most (all?) of the cases where I have seen people want
to use fuzzy equality for floats were situations where they were too
lazy/incompetent to do proper error analysis.  The fudge factors 0.99
and 1.01 look highly suspicious to me, and are likely to be bugs
waiting to happen.

****************************************************************

From: Robert Dewar
Sent: Wednesday, September 17, 2008  5:24 PM

> Incidentally, most (all?) of the cases where I have seen people want 
> to use fuzzy equality for floats were situations where they were too 
> lazy/incompetent to do proper error analysis.  The fudge factors 0.99 
> and 1.01 look highly suspicious to me, and are likely to be bugs 
> waiting to happen.

fuzzy equality for floats is a bad idea period! I agree entirely that
this is a dubious idea patching over incompetent programming.

Many coding standards forbid equality on floats. That's also misguided.
Equality is well defined for floats in IEEE arithmetic, and many
algorithms legitimately use equality, e.g. for abosolute conversion in
algorithms where such conversion is expected.
 
****************************************************************


Questions? Ask the ACAA Technical Agent