CVS difference for ais/ai-00364.txt

Differences between 1.3 and version 1.4
Log of other versions for file ais/ai-00364.txt

--- ais/ai-00364.txt	2004/01/23 04:59:29	1.3
+++ ais/ai-00364.txt	2004/03/02 01:43:25	1.4
@@ -1,4 +1,4 @@
-!standard  04.05.05(20)                                03-12-04  AI95-00364/00
+!standard  04.05.05(20)                                04-02-29  AI95-00364/01
 !class amendment 03-12-04
 !status received 03-09-29
 !priority Medium
@@ -7,16 +7,137 @@
 
 !summary
 
+This proposal attempts to alleviate the upward incompatibility
+created by Ada 95 for users defining their own fixed-point
+multiply or divide operators.
+
 !problem
 
+The pervasive visibility of universal-fixed multiply/divide operators
+coupled with the implicit conversion provided by Ada 95 resulted
+in an unforeseen incompatibility for users defining their own
+fixed-point multiply or divide operators. Essentially such operators
+are unusable, because the universal-fixed ones make any use of them
+ambiguous.
+
 !proposal
 
+Forbid use of universal-fixed multiply operator if both operands have
+at least one primitive user-defined multiply operator.
+Similarly, forbid use of universal-fixed divide operator if
+both operands have at least one primitive user-defined divide
+operator. These would be Name Resolution rules.
+
 !wording
 
+Change 4.5.5(20) as follows:
+
+           [Legality Rules] {Name Resolution}
+
+   The above two fixed-fixed multiplying operators shall not be used in a
+   context where the expected type for the result is itself universal_fixed
+   -- [the context has to identify some other numeric type to which the
+   result is to be converted, either explicitly or implicitly]. {An
+   explicit conversion is required on the result when using the above
+   fixed-fixed multiplication operator when both operands are of types with
+   user-defined primitive fixed-fixed multiplication operators. Similarly,
+   an explicit conversion is required on the result when using the above
+   fixed-fixed division operator when both operands are of types with
+   user-defined primitive fixed-fixed division operators.}
+
+     {AARM NOTE: We have made these into Name Resolution rules (one of them
+     existed in Ada95 but as a Legality Rule) to ensure that user-defined
+     primitive fixed-fixed operators are not made unusable due to the
+     presence of these universal fixed-fixed operators.}
+
+
 !discussion
 
+After taking a shot at defining the universal-access equality operators in
+standard, it became obvious that there is a simple fix for the
+universal-fixed incompatibility. Just have a name-resolution rule which
+forbids use of the universal-fixed operations if both operand types have at
+least one primitive user-defined multiply operator, in the case of the
+univ-fixed multiply op, or both have at least one primitive user-defined
+divide operator in the case of the univ-fixed divide op.
+
+This doesn't have any beaujolais effects, because it isn't a preference
+rule. Just certain fixed-point type combinations can't be used with the
+universal-fixed multiply/divide operators, based strictly on whether they
+both have their own primitive multiply/divide operators, even where these
+primitive operators are *not* visible.
+
+Note that we still allow the universal-fixed operators to be considered
+if there is an explicit conversion on the result. This is intended to provide
+Ada 83 compatibility. This implies that ambiguity is still possible, but
+only in the same places where ambiguity existed in Ada 83. A qualified
+expression on the result can be used to break the ambiguity in favor of
+the user-defined operator in such a situation, followed by the desired
+conversion. As in Ada 83, there is no way to make use of the
+universal-fixed operator if the operand types correspond to types
+for which there is a visible user-defined operator.
+
+OPEN ISSUE:
+  I phrased the suggested rule as requiring "both" to have a user-defined
+  primitive operator, but it could be phrased as "either." "Both" makes
+  sense if multiple fixed-point types are defined in the same scope.
+  "Either" makes sense if fixed-point types tend to be defined each in
+  their own package, because the "first" one defined would likely not have
+  any operators of its own. Compatibility with Ada 83 is enhanced by
+  specifying "either."  Compatibility with Ada 95 is enhanced by specifying
+  "both."  Because explicit conversion is always available as a fall back,
+  perhaps "either" is preferable, since it has less dependence on the
+  structure of the packages defining the fixed-point types.
+
+This isn't a totally hypothetical problem. At one point we definitely
+dealt with a customer who was trying to figure out how to get their old Ada
+83 fixed-point code to work, and the answer was not pretty. Basically they
+had to use non-operator functions like "mul" and "div", and live with the
+fact that they couldn't prevent misuse of the predefined univ-fixed
+operators.
+
+There are various reasons to want to "opt out" of the universal-fixed
+operators. In some cases the user-defined operator performs wrap-around or
+"saturation" arithmetic. In other cases, there may be a desire to limit
+what combinations of fixed-fixed types are allowed, so that only those that
+involve no scaling are permitted. This may be for efficiency, or simply
+for "physical units" consistency.
+
+With this rule, so long as each fixed point type has at least one primitive
+fixed-fixed "*" operator and one primitive fixed-fixed "/" operator, the
+univ-fixed operators will never be used.
+
 !example
 
+Here are three fixed-point types, with multiplication and
+division operators that require no scaling. These may
+be user-defined because they perform "saturation" arithmetic,
+or simply to ensure that they are only combined in ways that
+make sense.
+
+   type T1 is delta 0.1;
+   type T2 is delta 0.001;
+   type T3 is delta 0.0001;
+   function "*"(Left : T1; Right : T2) return T3;
+   function "*"(Left : T2; Right : T1) return T3;
+   function "/"(Left : T3; Right : T1) return T2;
+   function "/"(Left : T3; Right : T2) return T1;
+
+   X1, Y1 : T1 := ...;
+   X2, Y2 : T2 := ...;
+   X3, Y3 : T3;
+ begin
+   X3 := X1 * X2;  -- Does not use univ-fixed operator, no ambiguity
+   X3 := X1 * X1;  -- Error! Does not use univ-fixed operator, and
+                   -- no user-defined op works either
+   X1 := X3 / X2;  -- Does not use univ-fixed operator, no ambiguity
+   X3 := X1 / X2;  -- Error! Does not use univ-fixed operator,
+                   -- and no user-defined op works either
+   X3 := X3 * X3;  -- Error! Does not use univ-fixed operator (because
+                   -- X3 has a primitive which is fixed * fixed, even though
+                   -- X3 appears only as result type).
+   X3 := T3(X3 * X3);  -- OK, because of explicit conversion
+
 --!corrigendum
 
 !ACATS test
@@ -113,5 +234,31 @@
 don't know that the particular package ever got rewritten for Ada 95, but
 distance times sine returning distance, and (apparent) speed divided by cosine
 to give ground speed were two examples of where it was used in the code.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, March  1, 2004  6:29 PM
+
+Unless there is better motivation that Ada 83 compatibility, I would
+forget this. It's rather beside the point to worry about this issue
+at this stage, the damage is already done!
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March  1, 2004  7:34 PM
+
+Humm, is this the same Robert Dewar who wrote a few months ago:
+
+"We have run into similar situations. I like this fix. I think it is
+worth while. In fact I would suggest allowing Ada 95 compilers to do
+this right away, why not?"
+
+:-)
+
+Anyway, vendors have indicated that they have customers that have stuck with
+Ada 83 precisely because of this issue. Removing barriers to migration to
+newer versions Ada would seem to be valuable.
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent