!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. ****************************************************************