Version 1.1 of 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; --
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
--
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