!topic LSN on the Preference Rules in Ada 9X !key LSN-1037 on the Preference Rules in Ada 9X !reference MS-8.7;4.6 !reference RM83-4.6(15) !from Bob Duff $Date: 92/10/08 16:46:32 $ $Revision: 1.3 $ !discussion This Language Study Note discusses the preference rule of Ada 9X, which replaces the rule of RM83-4.6(15). The new rule (from the ILS) is: There is a preference for the primitive operators of the root numeric types root_integer and root_real. The rule is as follows: - In a given complete context, if two acceptable interpretations differ only in that one is for a primitive operator of the type root_integer or root_real, and the other is for a corresponding primitive operator for another numeric type, the interpretation using the primitive operator of the root numeric type is preferred. - For an innermost complete context, if there is exactly one overall acceptable interpretation where each constituent's interpretation is the same as or preferred (in the above sense) over those in all other overall acceptable interpretations, then that one overall acceptable interpretation is chosen. If the ambiguity cannot be resolved in this manner, the complete context is illegal. The reasons for this rule change are: - Nobody really understands what the Ada 83 rule means. - Implementations have chosen different interpretations of the Ada 83 rule. Thus, any upward compatibility concerns are irrelevant -- any upward incompatibility cannot possibly be worse than the current non-uniformity among compilers. - The "official" interpretation of the Ada 83 rule is so difficult to implement that it is not currently being enforced. To confirm this interpretation in Ada 9X, and to start properly enforcing the rules would be an enormous waste of compiler-writer's effort that could be better spent elsewhere. - The Ada 83 rule caused certain obscure Beaujolais effects. We believe that the new proposed rule solves the above problems. It has the following properties: - It is easier to understand what it means. - It is easily implementable in a local manner in the overload resolution algorithm. - Beaujolais effects are eliminated. - The new rule has identical effects to the official interpretation of the old rule, except in Beaujolais-related situations. Here is an example of an Ada 83 Beaujolais effect. A Beaujolais effect is a case where adding or subtracting a use_clause can cause a change from one legal interpretation to another. package P is procedure Q(B: Boolean); -- Q#1 end P; with P; procedure Main is function "<"(X, Y: Integer) return Integer; procedure Q(I: Integer) is ... -- Q#2 begin Q(1 < 2); end Main; As written, the call to Q unambiguously resolves to Q#2 -- the user-defined "<" operator is used, and the numeric literals are implicitly converted to type Integer. However, adding the use_clause "use P;" to Main causes it to unambiguously resolve to Q#1 (in Ada 83) -- the predefined "<" operator of universal_integer is used, and the numeric literals are NOT converted. That's because there is a legal interpretation of the complete context without implicit conversions, so implicit conversion is not done. This is the Beaujolais effect. In Ada 9X, adding the use_clause causes the call to Q to become ambiguous. That's because the two interpretations do not "differ only in that..." as required above. These Beaujolais examples are admittedly pathological. Nonetheless, it is a nice side-effect of the new rule that they are eliminated.