CVS difference for ai05s/ai05-0123-1.txt

Differences between 1.9 and version 1.10
Log of other versions for file ai05s/ai05-0123-1.txt

--- ai05s/ai05-0123-1.txt	2009/06/09 05:27:09	1.9
+++ ai05s/ai05-0123-1.txt	2009/07/11 03:06:22	1.10
@@ -1,5 +1,11 @@
-!standard  4.5.2(10-26)                                        09-04-07    AI05-0123-1/05
+!standard  4.5.2(9.7/2)                               09-06-29   AI05-0123-1/06
+!standard  4.5.2(14)
+!standard  4.5.2(15)
+!standard  4.5.2(24)
+!standard  8.5.4(8)
 !class Amendment 08-10-17
+!status Amendment 201Z 09-06-29
+!status ARG Approved  7-0-0  09-06-13
 !status work item 08-10-17
 !status received 08-09-03
 !priority Low
@@ -8,15 +14,15 @@
 
 !summary
 
-Primitive "=" ops for tagged and untagged records compose alike .
+Primitive "=" operators for tagged and untagged records compose alike.
 
 !problem
 
-A User-defined primitive "=" op for a tagged type "composes" in
+A user-defined primitive "=" operator for a tagged type "composes" in
 the sense that the predefined equality operator for an
 enclosing type which has one or more components of the given tagged
-type is defined in terms of the user-defined "=" op; the overridden
-predefined "=" op for the tagged type does not reemerge in this case.
+type is defined in terms of the user-defined "=" operator; the overridden
+predefined "=" operator for the tagged type does not reemerge in this case.
 
 This is not true for untagged types.
 
@@ -31,79 +37,15 @@
 
 !proposal
 
-If a nonlimited composite type contains a component
-of an untagged record type with a user-defined primitive
-"=" op, then the predefined equality op for the composite type
-is defined in terms of the user-defined equality op of the
+If a nonlimited composite type contains a component of an untagged
+record type with a user-defined primitive "=" operator, then the
+predefined equality operator for the composite type
+is defined in terms of the user-defined equality operator of the
 record type in the same way as if the record type were tagged.
 
-The situation is less clear for arrays because of the
-predefined lexicographic ordering operators for discrete array types
-(a change to "=" without a corresponding change to, say, "<=" seems
-like a bad idea). Thus, no analogous changes are proposed for
-array types.
-
-Tuck observes that "it would be pretty weird if the directly called
-equality didn't agree with the composed equality". For example, a
-call to the "=" operator for an untagged record type ought
-to yield the same answer aa a corresponding call to the the predefined
-"=" operator for a one-field record type whose one component is of
-the first record type.
-
-It is not clear how this principle applies in a some corner cases:
-   1) An untagged record type with a user-defined abstract
-      primitive "=" op.
-   2) An untagged record type declared in the visible part of a package
-      with a user-defined primitive "=" op declared in the private
-      part or the body of the package.
-   3) An untagged record type with a user-defined primitive "=" op
-      where the predefined "=" op is referenced before it is
-      overridden.
-
-Tuck suggests a general principle that 'you would either get a
-compile-time error, or always get the same semantics as Ada 2005
-for a direct call on "=" '.
-
-This suggests that the preceding corner cases might all defined
-to be illegal. That, however, is viewed as being too draconian.
-
-These cases are dealt with as follows:
-
-   1) The "composed" equality operator for a type with a component
-      whose primitive "=" operator is abstract is defined to raise
-      Program_Error at the point where the abstract function would
-      otherwise have been called. Similarly for the predefined equality
-      operator for an untagged record type whose primitive "=" operator
-      is abstract.
-   2) A user-defined primitive "=" operator for an untagged record type
-      may not be declared after the freezing point of the type,
-      nor may it be declared in the private part of a package
-      spec if (a full or partial view of) the record type is declared
-      in the visible part.
-   3) The case of an untagged record type with a user-defined primitive
-      "=" op where the predefined "=" op is referenced before it is
-      overridden is illegal except in the case of a rename of the
-      not-yet-overridden op. Such a rename has "squirreling"
-      semantics (see AARM 8.5.4(8.g))
-
-[Even if #2 and #3 get the usual boilerplate about rechecking in an
-expanded spec, there is still a question about violations within
-an expanded body. What are the dynamic semantics of a call to an
-overrider-pending "=" operator of a type derived from a formal private
-untagged type where the actual turns out to be a record type (tagged or
-untagged)? Or do we assume the worst and reject the generic body?]
-
-In the case of a generic formal private type where the corresponding
-actual parameter is an untagged record type with a user-defined
-primitive "=" op, reemergence does not take place. A call to the
-"=" operator associated with the formal type results in a call to
-the user-defined "=" op.
-
 !wording
 
-In 4.5.2, move the Legality Rules section from just ahead of the
-Static Semantics section to just after and then append at the end
-of the Legality Rules section:
+Add after 4.5.2(9.7/2):
 
   The explicit declaration of a primitive equality operator of an
   untagged record type shall occur before the type is frozen.
@@ -118,23 +60,26 @@
   predefined equality operator for the untagged record type.
 
 
-In 4.5.2(14), replace
+Replace 4.5.2(14):
 
   For a type extension, predefined equality is defined in terms of the
   primitive [(possibly user-defined)] equals operator of the parent type
   and of any tagged components of the extension part, and predefined
-  equality for any other components not inherited from the parent type. 
+  equality for any other components not inherited from the parent type.
 
 with
 
   For a type extension, predefined equality is defined in terms of the
-  primitive [(possibly user-defined)] equals operator of the parent type
-  and of any record components (tagged or untagged) of the extension part,
-  and predefined equality for any other components not inherited from the
+  primitive [(possibly user-defined)] equals operator for the parent type
+  and for any components of a record type in the extension part, and
+  predefined equality for any other components not inherited from the
   parent type.
 
+  For a derived type whose parent is an untagged record type, predefined equality
+  is defined in terms of the primitive (possibly user-defined) equals operator of
+  the parent type.
 
-In 4.5.2(15), replace 
+Replace 4.5.2(15):
 
   For a private type, if its full type is tagged, predefined equality is
   defined in terms of the primitive equals operator of the full type; if the
@@ -143,63 +88,115 @@
 
 with
 
-  For a private type, if its full type is a record type (tagged or untagged),
-  predefined equality is defined in terms of the primitive equals operator
-  of the full type; otherwise, predefined equality for the private type is
-  that of its full type.
+  For a private type, if its full type is a record type, predefined equality
+  is defined in terms of the primitive equals operator of the full type;
+  otherwise, predefined equality for the private type is that of its full type.
 
 
-In 4.5.2(24), replace
+Replace 4.5.2(24):
 
-  Otherwise, the result is defined in terms of the primitive equals operator
-  for any matching tagged components, and the predefined equals for any
-  matching untagged components. 
+  * Otherwise, the result is defined in terms of the primitive equals operator
+    for any matching tagged components, and the predefined equals for any
+    matching untagged components.
 
 with
 
-  Otherwise, the result is defined in terms of the primitive equals operator
-  for any matching record components (tagged or untagged), and the predefined
-  equals for any other matching components.
+  * Otherwise, the result is defined in terms of the primitive equals operator
+    for any matching components that are records, and the predefined
+    equals for any other matching components.
 
   If the primitive equals operator for an untagged record type is abstract,
   then Program_Error is raised at the point of any (implicit)
   call to that abstract subprogram.
 
-  AARM Note:
+  AARM Reason:
   An explicit call to an abstract subprogram is illegal.
   This rule is needed in order to define the effect of an
   implicit call such as a call that is part of the
   predefined equality operation for an enclosing composite type
   that has a component of an untagged record type that has an
-  abstract primitive equals operator.
+  abstract primitive equals operator. For tagged types, an abstract
+  primitive equals operator is only allowed for an abstract type,
+  and abstract types cannot be components, so this case does not occur.
 
 
-In 32.a.1/1, replace
+In AARM 4.5.2(32.a.1/1), replace
   "then either the full type must be tagged"
 with
   "then either the full type must be a record type" .
 
 
-Append after 8.5.4(7.1/1)
+Append after 8.5.4(8):
 
   A corresponding rule applies to a call on a renaming of
-  a predefined equality operator for an untagged record type 
-  that is overridden if the overriding occurs after the renaming.
+  a predefined equality operator for an untagged record type.
 
-   
+
 !discussion
 
-Is the cure worse than the disease?
-Should this whole AI should be abandoned?
-This is the most important question about the AI. Note that the cost of this
-AI is incurred in several areas - the RM becomes more complex,
-implementations becomes more complex, an inconsistency between
-the treatment of records and arrays is introduced,
-and some (hopefully unimportant) incompatibilities are introduced.
+We do not include arrays because of the predefined lexicographic ordering
+operators for discrete array types. Since these rules change what "="
+operator is used within a generic, we could have a situation where
+"=" is user-defined but the predefined "<=" reemerges. This would be
+bad as the two operators would no longer have the correspondence that
+the creator of the abstraction intended.
+
+Note that arrays with a component type that is a record with a user-defined "="
+will compose "=" correctly (the predefined array "=" will use the user-defined
+"=" on the components); this just means that arrays with user-defined "=" will
+not have that "=" compose. (It is likely that the "=" exists simply because the
+components did not compose in earlier versions of Ada, so that this will make no
+difference.)
 
-----
+---
+
+It would be pretty weird if the directly called equality didn't agree with
+the composed equality. For example, a call to the "=" operator for an
+untagged record type R ought to yield the same answer as a corresponding call
+to the predefined "=" operator for a one-field record type whose one
+component is type R.
+
+If that is not possible (or the semantics would change from Ada 2005 for
+a direct call on "="), then you should get a compile-time or run-time error
+from a direct call on "=".
+
+We handle some corner cases as follows:
+
+ 1) The "composed" equality operator for a type with a component
+    whose primitive "=" operator is abstract is defined to raise
+    Program_Error. This is only possible for a component of
+    an untagged record type.
+
+    We made this a run-time error as making the type declaration illegal
+    would make programs illegal even if they didn't call "=". Making
+    any call on "=" illegal in this case would cause a significant
+    generic contract issue: we would have to assume the worst in
+    a generic body for any formal private type -- meaning that "="
+    could never be used there. That's obviously too incompatible to
+    seriously consider.
+
+ 2) A user-defined primitive "=" operator for an untagged record type
+    may not be declared after the freezing point of the type,
+    nor may it be declared in the private part of a package
+    spec if (a full or partial view of) the record type is declared
+    in the visible part.
+
+    This preserves the principle that "=" always calls the same
+    body no matter what view of the type is available. Otherwise the
+    implementation of "=" called could depend on the view of the
+    of the type, which would be a nightmare for composition.
+
+ 3) Referencing a predefined "=" operator in a renames before
+    overriding the "=" operator is treated as having "squirreling"
+    semantics (see AARM 8.5.4(8.g))
 
+!example
+
+The order of declarations does not matter when determining what body for "=" is
+called.
+
 Consider the following example:
+
    package Pkg is
      type Rec is null record;
      function "=" (L, R) return Boolean is abstract;
@@ -213,17 +210,18 @@
 
 Vec's predefined "=" operator is defined in terms of that of Drec,
 which is defined in terms of the explicitly defined "=" operator.
+Thus, "=" for Vec does not necessarily raise Program_Error.
 
---------
 
 Consider the following example:
+
      package P is
        type T is limited private;
        package Inner is
          type Rec is record X : T; end record;
        end Inner;
-     private
        function "=" (L, R : T) return Boolean is abstract;
+     private
        type T is null record;
      end P;
 
@@ -236,60 +234,87 @@
 
 The elaboration of the declaration of Flag raises Program_Error.
 
-----
+!corrigendum 4.5.2(9.7/2)
 
-The proposed wording in 8.5.4 uses "A corresponding rule", even though
-existing wording in 7.3.1(4/1) uses "The corresponding rule".
-Should the two agree? If so, then should 7.3.1 be changed?
+@dinsa
+@xbullet<When both are access-to-subprogram types, the designated profiles
+shall be subtype conformant.>
+@dinst
+The explicit declaration of a primitive equality operator of an
+untagged record type shall occur before the type is frozen.
+If the untagged record type has a nonlimited partial view, then the
+declaration shall occur in the visible part of the enclosing package.
+In addition to the places where Legality Rules normally apply (see 12.3),
+this rule applies also in the private part of an instance of a generic unit.
+
+!corrigendum 4.5.2(14)
+
+@drepl
+For a type extension, predefined equality is defined in terms of the
+primitive [(possibly user-defined)] equals operator of the parent type
+and of any tagged components of the extension part, and predefined
+equality for any other components not inherited from the parent type.
+@dby
+For a type extension, predefined equality is defined in terms of the
+primitive [(possibly user-defined)] equals operator for the parent type
+and for any record components in the extension part, and predefined
+equality for any other components not inherited from the parent type.
+
+For a derived type whose parent is an untagged record type, predefined equality
+is defined in terms of the primitive (possibly user-defined) equals operator of
+the parent type.
+
+!corrigendum 4.5.2(15)
+
+@drepl
+For a private type, if its full type is tagged, predefined equality is
+defined in terms of the primitive equals operator of the full type; if the
+full type is untagged, predefined equality for the private type is that of
+its full type.
+@dby
+For a private type, if its full type is a record type, predefined equality
+is defined in terms of the primitive equals operator of the full type;
+otherwise, predefined equality for the private type is that of its full type.
+
+!corrigendum 4.5.2(24)
+
+@drepl
+@xbullet<Otherwise, the result is defined in terms of the primitive equals
+operator for any matching tagged components, and the predefined equals for any
+matching untagged components.>
+@dby
+@xbullet<Otherwise, the result is defined in terms of the primitive equals
+operator for any matching components that are records, and the predefined
+equals for any other matching components.>
+
+If the primitive equals operator for an untagged record type is abstract,
+then Program_Error is raised at the point of any (implicit)
+call to that abstract subprogram.
+
+!corrigendum 8.5.4(8)
+
+@drepl
+For a call on a renaming of a dispatching subprogram that is overridden, if the
+overriding occurred before the renaming, then the body executed is that of the
+overriding declaration, even if the overriding declaration is not visible at the
+place of the renaming; otherwise, the inherited or predefined subprogram is
+called.
+@dby
+For a call on a renaming of a dispatching subprogram that is overridden, if the
+overriding occurred before the renaming, then the body executed is that of the
+overriding declaration, even if the overriding declaration is not visible at the
+place of the renaming; otherwise, the inherited or predefined subprogram is
+called. A corresponding rule applies to a call on a renaming of a predefined
+equality operator for an untagged record type.
 
---------
 
-This would add the 25th occurrence in the
-RM of the famous "In addition to the places where
-Legality Rules normally apply ..." boilerplate.
 
-The need for an AI which would make that the default
-rule and explicitly enumerate the exceptions in the
-opposite direction (e.g., no homograph collisions in
-a declarative region) slowly builds.
-
----------
-
-The decision to treat arrays and records inconsistently
-may have been a mistake.
-
-It seems odd that replacing
-
-  type Foo is array (Positive range <>) of Element;
-  function "=" (L, R : Foo) return Boolean;
-
-with
-
-  type Foo_Implementation is array (Positive range <>) of Element;
-  type Foo (Last : Natural) is
-    record
-      Elements : Foo_Implementation (1 .. Last);
-    end record;
-  function "=" (L, R : Foo) return Boolean;
-
-could cause a program to start behaving differently in mysterious ways.
-
-The argument was made that we don't want to introduce an
-inconsistency in the behavior of "=" and, for example, "<=" for
-a discrete array type. This makes no sense. Nobody is
-talking about changing the behavior of a composite type's
-equality op if someone adds/deletes a user-defined equality op for
-an *elementary* component type. A function whose behavior might
-be affected by this decision would be the predefined equality operator for
-some type which includes this array type as a component type.
-
-!example
-
-** TBD **
-    
 !ACATS test
 
-** TBD **
+ACATS C-Tests should be constructed to check that composition is implemented as
+required. ACATS B-Tests should be constructed to check that the legality rules
+are properly implemented. Any existing tests requiring reemergence should be
+repaired/withdrawn.
 
 !appendix
 
@@ -429,10 +454,10 @@
 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 
+> 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
@@ -442,7 +467,7 @@
 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.
- 
+
 ****************************************************************
 
 From: John Barnes
@@ -465,7 +490,7 @@
 I think it was Pascal that suggested that the pragma should only be
 applicable to nontagged records.
 
-Incidentally I believe the RM says that all predefined types are composable. 
+Incidentally I believe the RM says that all predefined types are composable.
 Where is it?  I seem to recall a discussion on this when doing Ada 95. Are
 they composable because they behave as if the proposed pragma has been
 applied (ie magic) or are they composable because the predefined equality
@@ -673,7 +698,7 @@
 From: Edmond Schonberg
 Sent: Monday, October 20, 2008  12:18 PM
 
-> Ed, how about we instrument GNAT to see how many cases in our test 
+> Ed, how about we instrument GNAT to see how many cases in our test
 > suite would be affected by such a change
 
 We could check on all uses of predefined equality on records for which
@@ -730,7 +755,7 @@
 From: Edmond Schonberg
 Sent: Monday, October 20, 2008  5:40 PM
 
-> But both of these types are required to have composable equality by 
+> But both of these types are required to have composable equality by
 > the language definition (see RM 4.5.2(32.1/1)).
 
 And indeed they compose properly. no problem here.  My mod to the
@@ -914,7 +939,7 @@
 From: Robert Dewar
 Sent: Tuesday, October 21, 2008  10:30 AM
 
-> By the way Robert, what have emerged as the biggest incompatibilities 
+> By the way Robert, what have emerged as the biggest incompatibilities
 > in Ada 2005, in AdaCore's experience?
 > I presume the loss of by-reference function return is one.  Others?
 
@@ -1004,6 +1029,7 @@
 see Ravenscar.
 
 ****************************************************************
+
 From: Robert Dewar
 Sent: Tuesday, October 21, 2008  11:26 AM
 
@@ -1052,11 +1078,11 @@
 From: Edmond Schonberg
 Sent: Tuesday, October 21, 2008  12:06 PM
 
->> Conclusion from this small sample: having equality compose would be 
+>> Conclusion from this small sample: having equality compose would be
 >> harmless, and of course clearer conceptually.
 >
-> No ACATS tests? They wouldn't prove anything other than whether 
-> compilers are actually doing this all the same way (no test would mean 
+> No ACATS tests? They wouldn't prove anything other than whether
+> compilers are actually doing this all the same way (no test would mean
 > no certainty of portability in this area).
 
 Indeed, no ACATS tests (either B or C) that have a comparison of
@@ -1074,7 +1100,7 @@
 records.
 
 I also think that proper names for the pragmas should make it clear which
-one to use in your code if you are a belt and suspenders type.. 
+one to use in your code if you are a belt and suspenders type..
 (Only needed of course, if you define an equality operation for a type.)
 
 pragma Equality_Composes( For => Base_Type); --seems right, with
@@ -1095,8 +1121,8 @@
 Sent: Wednesday, October 22, 2008  8:14 PM
 
 ...
-> BTW what was the original motivation behind the rule? Given that it 
-> does not work for fpt to do block compares, the whole thing seems 
+> BTW what was the original motivation behind the rule? Given that it
+> does not work for fpt to do block compares, the whole thing seems
 > silly to me.
 
 I was hoping to answer this question, since I was wondering about that
@@ -1152,10 +1178,10 @@
 Sent: Wednesday, October 22, 2008  10:11 PM
 
 ...
->So, unless John Goodenough has the answer in his huge stack of paper 
->discussions [and finding it in there is not likely to be easy], I'm 
+>So, unless John Goodenough has the answer in his huge stack of paper
+>discussions [and finding it in there is not likely to be easy], I'm
 >afraid the reason is lost to the mists of time.
- 
+
 If you are asking about the non-composition of equality in records, that is
 certainly not lost.  The intent was to allow comparison for records to be
 implemented as a bit for bit* comparison.  The same holds true for arrays,
@@ -1191,7 +1217,7 @@
 never used once VM started.)
 
 * Of course, compilers were expected to optimize these compares to use byte,
-16-bit, 32-bit, etc. compare instructions when possible. (Now, 64. 
+16-bit, 32-bit, etc. compare instructions when possible. (Now, 64.
 128. and soon 256-bit operations.) Early compilers, though, were doing
 good if they used string compare instructions for String.  Dave Emery
 wrote a move for records in Ada that used 32-bit instructions (and
@@ -1206,14 +1232,14 @@
 From: Robert Dewar
 Sent: Thursday, October 23, 2008  7:30 AM
 
-> If you are asking about the non-composition of equality in records, 
-> that is certainly not lost.  The intent was to allow comparison for 
-> records to be implemented as a bit for bit* comparison.  The same 
-> holds true for arrays, at least for equality of arrays of boolean and 
-> enumeration types.  I do remember lots of discussion prior to Ada 83 
-> being finalized about equality for floating point in the presence of 
-> potentially unnormalized values.  But that basically went away with 
-> the hardware that permitted it.  Both the IEEE and DEC floating point 
+> If you are asking about the non-composition of equality in records,
+> that is certainly not lost.  The intent was to allow comparison for
+> records to be implemented as a bit for bit* comparison.  The same
+> holds true for arrays, at least for equality of arrays of boolean and
+> enumeration types.  I do remember lots of discussion prior to Ada 83
+> being finalized about equality for floating point in the presence of
+> potentially unnormalized values.  But that basically went away with
+> the hardware that permitted it.  Both the IEEE and DEC floating point
 > formats have a single valid representation for every value--at least within types.
 
 not true, +0.0 and =0.0 must compare equal!
@@ -1223,10 +1249,10 @@
 From: Randy Brukardt
 Sent: Thursday, October 23, 2008  7:12 PM
 
-> You weren't allowed to redefine equality for non-limited types in Ada 
+> You weren't allowed to redefine equality for non-limited types in Ada
 > 83, so the problem didn't arise.
-> Why weren't you allowed to redefine equality?  I suspect because you 
-> weren't allowed to redefine assignment, and there is an implicit 
+> Why weren't you allowed to redefine equality?  I suspect because you
+> weren't allowed to redefine assignment, and there is an implicit
 > connection between equality and assignment.
 
 Well, obviously that wasn't true in practice (the Goodenough trick was widely
@@ -1272,7 +1298,8 @@
 From: Randy Brukardt
 Sent: Thursday, October 23, 2008  7:29 PM
 
-I know. I've been wondering if someone else at AdaCore is using your e-mail account. ;-)
+I know. I've been wondering if someone else at AdaCore is using your e-mail
+account. ;-)
 
 ****************************************************************
 
@@ -1293,16 +1320,16 @@
 From: Randy Brukardt
 Sent: Thursday, October 23, 2008  7:25 PM
 
-> > If you are asking about the non-composition of equality in records, 
-> > that is certainly not lost.  The intent was to allow comparison for 
-> > records to be implemented as a bit for bit* comparison.  The same 
+> > If you are asking about the non-composition of equality in records,
+> > that is certainly not lost.  The intent was to allow comparison for
+> > records to be implemented as a bit for bit* comparison.  The same
 > > holds true for arrays, at least for equality of arrays of boolean and
 > > enumeration types.  I do remember lots of discussion prior to Ada 83
 > > being finalized about equality for floating point in the presence of
-> > potentially unnormalized values.  But that basically went away with 
+> > potentially unnormalized values.  But that basically went away with
 > > the hardware that permitted it.  Both the IEEE and DEC floating point
 > > formats have a single valid representation for every value--at least within types.
-> 
+>
 > not true, +0.0 and =0.0 must compare equal!
 
 Not to mention that it doesn't work for one's complement Integers (as we found
@@ -1378,8 +1405,8 @@
 From: Randy Brukardt
 Sent: Thursday, November 13, 2008  8:30 PM
 
-That seems like adding a compatibility issue where one is not necessarily needed.
-Wouldn't it make more sense to simply say that "late" overridings don't
+That seems like adding a compatibility issue where one is not necessarily
+needed. Wouldn't it make more sense to simply say that "late" overridings don't
 participate in composition? Existing code with late equality definitions surely
 doesn't depend on composition, and breaking it solely so composition (that they
 don't use) works seems like a good way to get the idea dropped.
@@ -1399,18 +1426,18 @@
 where the programmer might presume they are getting composable equality when
 they aren't.
 
-I think this is a very minor incompatibility, and it is clearly one that would be
-caught by the compiler.  If we believe that providing composability for equality
-will fix more bugs than it will introduce, we should make illegal any situation
-where you *don't* get composability when it seemed like you might.  Having a
-"half-and-half" situation seems dangerous, since there will be no easy answer
-to what user-defined equality operators are composable. That isn't doing anybody
-any favors.
+I think this is a very minor incompatibility, and it is clearly one that would
+be caught by the compiler.  If we believe that providing composability for
+equality will fix more bugs than it will introduce, we should make illegal any
+situation where you *don't* get composability when it seemed like you might.
+Having a "half-and-half" situation seems dangerous, since there will be no easy
+answer to what user-defined equality operators are composable. That isn't doing
+anybody any favors.
 
 By the way, when I use the term "late overriding" I mean for a type declared in
 a package spec, overriding a primitive in the package body or after the type is
-frozen. That's not allowed for tagged types, but it is allowed for untagged types
-(and it's a bit of a pain to implement, by the way ;-).
+frozen. That's not allowed for tagged types, but it is allowed for untagged
+types (and it's a bit of a pain to implement, by the way ;-).
 
 ****************************************************************
 
@@ -1422,10 +1449,10 @@
 That's all I thought.
 
 ...
-> By the way, when I use the term "late overriding" I mean for a type 
-> declared in a package spec, overriding a primitive in the package body 
+> By the way, when I use the term "late overriding" I mean for a type
+> declared in a package spec, overriding a primitive in the package body
 > or after the type is frozen.
-> That's not allowed for tagged types, but it is allowed for untagged 
+> That's not allowed for tagged types, but it is allowed for untagged
 > types (and it's a bit of a pain to implement, by the way ;-).
 
 I could see banning it in a spec (it's easy to fix by moving the declaration
@@ -1437,10 +1464,10 @@
 intended for local use. (I have debugging equality routines like that.) Making
 the user put it into the spec (thus making it available to the world) or making
 them rename it seems like changes that could only cause bugs (it surely isn't
-going to fix any - they're not depending on composible equality). Remember,
-the GNAT survey didn't find many instances of anyone using a potentially composed
-equality; but that doesn't mean that there isn't use of redefined equality,
-even locally only.
+going to fix any - they're not depending on composible equality). Remember, the
+GNAT survey didn't find many instances of anyone using a potentially composed
+equality; but that doesn't mean that there isn't use of redefined equality, even
+locally only.
 
 P.S. I wouldn't consider anything that happens in the body as "overriding"
 anyway. "Overriding" is really about inheritance, and there isn't any of that
@@ -1452,10 +1479,10 @@
 Sent: Thursday, November 13, 2008  9:51 PM
 
 > P.S. I wouldn't consider anything that happens in the body as "overriding"
-> anyway. "Overriding" is really about inheritance, and there isn't any 
+> anyway. "Overriding" is really about inheritance, and there isn't any
 > of that going on in a body.
 
-Ahhh, but there you are wrong!  Primitives that are overridden *are* 
+Ahhh, but there you are wrong!  Primitives that are overridden *are*
 inherited, even if the overriding happens very "late" (e.g. in the body).
 E.g.:
 
@@ -1492,7 +1519,7 @@
 test below if you're as curious as I was...)
 
 > I think this should be illegal for record equality.
-> Did you imply in your earlier message that you actually do this kind 
+> Did you imply in your earlier message that you actually do this kind
 > of thing?  Wouldn't you expect composability if it were legal?
 
 I surely didn't derive an untagged type in a body; I consider deriving
@@ -1505,7 +1532,7 @@
 *only* wanted to debug stuff going on in that body, and I surely did not want
 it affecting anything else. If I had wanted *that*, I'd have put it in the spec
 so the world could see it! So I think your suggested new requirement would be
-actively harmful in this particular case. 
+actively harmful in this particular case.
 
 I don't want to imply that this is some sort of deal-breaker, because it's
 not: user-defined record equality isn't that common, and besides, all new types
@@ -1554,11 +1581,11 @@
 From: Steve Baird
 Sent: Friday, November 14, 2008  2:56 PM
 
-> For tagged types, we say that even if an overriding takes place in the 
-> private part, the code executed for a call on a primitive operation is 
+> For tagged types, we say that even if an overriding takes place in the
+> private part, the code executed for a call on a primitive operation is
 > independent of visibility.
-> I think if we are going to try to make record equality work the same 
-> whether the type is tagged or not, we should probably adopt this 
+> I think if we are going to try to make record equality work the same
+> whether the type is tagged or not, we should probably adopt this
 > principle for all record equality.
 
 
@@ -1621,27 +1648,27 @@
 It's not clear to me what you mean by this, at least in the first case.
 
 I originally thought that you meant that calling "=" for such an equality would
-be illegal. That would be what the programmer intended, but I don't see how to do
-that without nasty generic contract problems.
+be illegal. That would be what the programmer intended, but I don't see how to
+do that without nasty generic contract problems.
 
 OTOH, if you mean that declaring an abstract "=" is illegal, that seems like a
 significant incompatibility. For one thing, that would render ASIS '99 illegal
-(and leave us stuck again with the problem of how to change that for the new ASIS,
-one that we could not usefully decide any improvement to the last time we looked
-at it). It also means that anyone who tried to undefine "=" as ASIS did would be
-broken (and left with no workaround other than redefining "=" to raise an
-exception -- going from compile-time to run-time detection of errors is not going
-in the right direction). So this doesn't seem like a good idea, either.
-
-My understanding is that Tucker suggested that abstract equality would essentially
-work as it does now (the predefined "=" would re-emerge in cases where a direct
-illegality of the call is impossible), since it isn't reasonable to make all such
-cases statically illegal. (Your quote of him says as much.) You seem to be trying
-to make all such cases illegal, reasonable or not.
+(and leave us stuck again with the problem of how to change that for the new
+ASIS, one that we could not usefully decide any improvement to the last time we
+looked at it). It also means that anyone who tried to undefine "=" as ASIS did
+would be broken (and left with no workaround other than redefining "=" to raise
+an exception -- going from compile-time to run-time detection of errors is not
+going in the right direction). So this doesn't seem like a good idea, either.
+
+My understanding is that Tucker suggested that abstract equality would
+essentially work as it does now (the predefined "=" would re-emerge in cases
+where a direct illegality of the call is impossible), since it isn't reasonable
+to make all such cases statically illegal. (Your quote of him says as much.) You
+seem to be trying to make all such cases illegal, reasonable or not.
 
 The best idea I can think of would be that if a component that has a record type
-has abstract equality, then the composed equality is also abstract.
-(This case can't happen currently for a non-abstract tagged type, because abstract
+has abstract equality, then the composed equality is also abstract. (This case
+can't happen currently for a non-abstract tagged type, because abstract
 operations are only allowed on abstract tagged types. In the abstract case, the
 result would be the same.) That would make direct calls to "=" illegal in that
 case. Generics, however, would still re-emerge.
@@ -1651,14 +1678,15 @@
 From: Tucker Taft
 Sent: Monday, November 17, 2008  4:54 PM
 
-I would agree with all but the case of an abstract primitive "=".
-That seems to be a useful way to say that although copying is well defined, there
-isn't a single "=" that always makes sense.
+I would agree with all but the case of an abstract primitive "=". That seems to
+be a useful way to say that although copying is well defined, there isn't a
+single "=" that always makes sense.
 
 To preserve "the principle", the "composed" equality for a type with such a type
-as a subcomponent would also be abstract. Any type with an abstract composable "="
-could not be passed as an actual to a non-limited formal private or derived type
-(unless the ancestor type of the formal derived type similarly has an abstract "=").
+as a subcomponent would also be abstract. Any type with an abstract composable
+"=" could not be passed as an actual to a non-limited formal private or derived
+type (unless the ancestor type of the formal derived type similarly has an
+abstract "=").
 
 That's pretty draconian, but not as draconian as making the abstract "=" illegal
 from the get-go.
@@ -1668,40 +1696,41 @@
 From: Randy Brukardt
 Sent: Monday, November 17, 2008  5:02 PM
 
-As soon as I pressed "send" on my reply to Steve, I thought of a Baird-like problem
-with this. (Since this is Steve's AI, someone else will have to take his role of
-blowing up all of the good ideas!)
-
-This solution (proposed by both you and me without knowledge of the other) doesn't
-work for a concrete tagged type that has an extension component that has an
-abstract "=" operation. (Such a component would have to be untagged.) In that case,
-this rule would make the "=" abstract, but that would violate the principle that
-no concrete tagged type has an abstract operation. And that principle is very
-important if dispatching is allowed.
+As soon as I pressed "send" on my reply to Steve, I thought of a Baird-like
+problem with this. (Since this is Steve's AI, someone else will have to take his
+role of blowing up all of the good ideas!)
+
+This solution (proposed by both you and me without knowledge of the other)
+doesn't work for a concrete tagged type that has an extension component that has
+an abstract "=" operation. (Such a component would have to be untagged.) In that
+case, this rule would make the "=" abstract, but that would violate the
+principle that no concrete tagged type has an abstract operation. And that
+principle is very important if dispatching is allowed.
 
 One could make an exception and have "=" re-emerge in that case, but once you do
 that, why bother with any of it??
 
-So I now have killed off *all* of the (static) ideas for this one. Anyone else have
-an idea???
+So I now have killed off *all* of the (static) ideas for this one. Anyone else
+have an idea???
 
 ****************************************************************
 
 From: Tucker Taft
 Sent: Monday, November 17, 2008  5:14 PM
 
-I think this is fairly straightforward.  The tagged type gets an abstract predefined
-"=" and if the tagged type is not itself abstract, then the "=" must be overridden.
-This would be true similarly if its parent type had an abstract "=".
+I think this is fairly straightforward.  The tagged type gets an abstract
+predefined "=" and if the tagged type is not itself abstract, then the "=" must
+be overridden. This would be true similarly if its parent type had an abstract
+"=".
 
 ****************************************************************
 
 From: Tucker Taft
 Sent: Monday, November 17, 2008  4:57 PM
 
-I guess I would also allow you to "squirrel away" the predefined "="
-by renaming it before it was overridden.  I'm not sure whether you intended that
-to be illegal as well, but it is frequently useful.
+I guess I would also allow you to "squirrel away" the predefined "=" by renaming
+it before it was overridden.  I'm not sure whether you intended that to be
+illegal as well, but it is frequently useful.
 
 ****************************************************************
 
@@ -1710,23 +1739,24 @@
 
 This one is turning out to be more complicated than I expected. I've attached
 another attempt at a !discussion and !proposal section, featuring (by popular
-demand) support for squirreling renames of equality operations that are going
-to be overridden by abstract functions. [This one is version /03 of the AI - Editor.]
+demand) support for squirreling renames of equality operations that are going to
+be overridden by abstract functions. [This one is version /03 of the AI -
+Editor.]
 
 ****************************************************************
 
 From: Tucker Taft
 Sent: Monday, November 17, 2008  8:16 PM
 
-> [Even if #2 and #3 get the usual boilerplate about rechecking in an 
-> expanded spec, there is still a question about violations within an 
-> expanded body. What are the dynamic semantics of a call to an 
-> overrider-pending "=" operator of a type derived from a formal private 
-> untagged type where the actual turns out to be a record type (tagged 
+> [Even if #2 and #3 get the usual boilerplate about rechecking in an
+> expanded spec, there is still a question about violations within an
+> expanded body. What are the dynamic semantics of a call to an
+> overrider-pending "=" operator of a type derived from a formal private
+> untagged type where the actual turns out to be a record type (tagged
 > or untagged)? Or do we assume the worst and reject the generic body?]
 
-I think you assume the worst in a generic body.  That is, if you derive in
-the body from a nonlimited, untagged formal private type, you should presume it
+I think you assume the worst in a generic body.  That is, if you derive in the
+body from a nonlimited, untagged formal private type, you should presume it
 might be an untagged record type, and enforce the restrictions.  I can't imagine
 this will be too constraining!
 
@@ -1749,20 +1779,20 @@
 From: Randy Brukardt
 Sent: Thursday, December 4, 2008  11:19 PM
 
-> I think you assume the worst in a generic body.  That is, if you 
-> derive in the body from a nonlimited, untagged formal private type, 
-> you should presume it might be an untagged record type, and enforce 
+> I think you assume the worst in a generic body.  That is, if you
+> derive in the body from a nonlimited, untagged formal private type,
+> you should presume it might be an untagged record type, and enforce
 > the restrictions.  I can't imagine this will be too constraining!
 
 Humm; generally we want regular private types and formal private types to work
-the same way. And even though Mr. Private is (mostly) retired, I doubt that
-we want to break privacy to make such a check. So I think we have to enforce
-these restrictions on *all* untagged private types (because they might actually
-be an untagged record type).
+the same way. And even though Mr. Private is (mostly) retired, I doubt that we
+want to break privacy to make such a check. So I think we have to enforce these
+restrictions on *all* untagged private types (because they might actually be an
+untagged record type).
 
 For instance:
 
-    package P is 
+    package P is
        type Priv is private;
     private
        type Priv is access ...; -- (1)
@@ -1794,10 +1824,10 @@
 From: Tucker Taft
 Sent: Friday, December 5, 2008  12:00 AM
 
-I agree this is a simpler and better solution.  Namely, all untagged private types,
-whether formal private or package private, are treated as though they are untagged
-record types, so no "late" or "private" primitive definition of "=" may be given
-for any descendant of one.
+I agree this is a simpler and better solution.  Namely, all untagged private
+types, whether formal private or package private, are treated as though they are
+untagged record types, so no "late" or "private" primitive definition of "=" may
+be given for any descendant of one.
 
 ****************************************************************
 
@@ -1806,7 +1836,7 @@
 
 > Humm; generally we want regular private types and formal private types to
 > work the same way. And even though Mr. Private is (mostly) retired, I doubt
-> that we want to break privacy to make such a check. 
+> that we want to break privacy to make such a check.
 
 Retired but watchful.  I think you are perfectly right, you need to reject the
 private "=" in your example.  Not only is this AI getting more and more hairy
@@ -1851,8 +1881,8 @@
 Sent: Friday, December 5, 2008  4:23 PM
 
 Well, let's not fall into the trap of "we've done a lot of work on X, so we have
-to include X in the final thing, or all that work will be wasted".
-It's easy to do that, subconciously.
+to include X in the final thing, or all that work will be wasted". It's easy to
+do that, subconciously.
 
 I think that's what happened with anonymous access types.
 It would have been better to leave them out, IMHO, since they don't solve the
@@ -1862,10 +1892,10 @@
 anon acc types.
 
 Also, in a world where only one implementer has implemented Ada 2005, and only
-just barely, I'm not inclined to spend a lot of energy on Sausage 2015 -- I think
-it should be a modest update, compared to Adas 95 and 2005, which were both quite
-huge.  It would be good for Ada, and good for the world, to have more than one
-up-to-date Ada implementation.
+just barely, I'm not inclined to spend a lot of energy on Sausage 2015 -- I
+think it should be a modest update, compared to Adas 95 and 2005, which were
+both quite huge.  It would be good for Ada, and good for the world, to have more
+than one up-to-date Ada implementation.
 
 ****************************************************************
 
@@ -1895,8 +1925,8 @@
 Sent: Saturday, December 6, 2008  5:23 AM
 
 Hmm, I am a bit lost in the discussion, with no wording in the AI and comforting
-statements like "It is not clear how this principle applies in a some corner cases".
-I'd like to understand what happens in a case like this:
+statements like "It is not clear how this principle applies in a some corner
+cases". I'd like to understand what happens in a case like this:
 
 package P is
    type T is private;
@@ -1905,102 +1935,104 @@
    type T is new BS.Bounded_String;
 end P;
 
-Here Bounded_String has a user-defined "=", which is inherited by T.  Does that mean
-that the above example is illegal?  Hopefully I am confused and it is not, otherwise
-it is an horrendous incompatibility.
+Here Bounded_String has a user-defined "=", which is inherited by T.  Does that
+mean that the above example is illegal?  Hopefully I am confused and it is not,
+otherwise it is an horrendous incompatibility.
 
 ****************************************************************
 
 From: Tucker Taft
 Sent: Sunday, December 7, 2008  8:27 AM
 
-We will definitely need to do some wording if we want to assess the incompatibility.
-Here is paragraph 15 from 4.5.2, with possible changes marked:
+We will definitely need to do some wording if we want to assess the
+incompatibility. Here is paragraph 15 from 4.5.2, with possible changes marked:
 
    For a private type, if its full type is [tagged]{a record type},
    predefined equality is defined in terms of the primitive equals
    operator of the full type; [if the full type is untagged]{otherwise},
    predefined equality for the private type is that of its full type.
 
-Given the above, I'm not sure we need to worry so much about private types.  I think
-the thing we need to worry about are record types.  For those, the predefined "=" may
-only be overridden visibly.  Overriding it privately or after the freezing point should
-be illegal.
+Given the above, I'm not sure we need to worry so much about private types.  I
+think the thing we need to worry about are record types.  For those, the
+predefined "=" may only be overridden visibly.  Overriding it privately or after
+the freezing point should be illegal.
 
 ****************************************************************
 
 From: Randy Brukardt
 Sent: Monday, December 8, 2008  1:37 PM
 
-But "full type" is the problem here: how is that enforced in generics for private
-formals and when deriving from a private type whose full type is a record type? You
-can't break privacy to make such a legality check, so you have to assume the worst.
-Which is how it ends up applying to private types.
-
-Now, I think it is perfectly reasonable to forget the legality rules here and only
-make the change you note above. (That's a dynamic semantics rule, after all, it can
-ignore privacy.) The problem comes from trying to enforce points of declaration
-statically.
+But "full type" is the problem here: how is that enforced in generics for
+private formals and when deriving from a private type whose full type is a
+record type? You can't break privacy to make such a legality check, so you have
+to assume the worst. Which is how it ends up applying to private types.
+
+Now, I think it is perfectly reasonable to forget the legality rules here and
+only make the change you note above. (That's a dynamic semantics rule, after
+all, it can ignore privacy.) The problem comes from trying to enforce points of
+declaration statically.
 
 ****************************************************************
 
 From: Tucker Taft
 Sent: Tuesday, December 9, 2008  12:16 AM
 
-> But "full type" is the problem here: how is that enforced in generics 
-> for private formals and when deriving from a private type whose full 
+> But "full type" is the problem here: how is that enforced in generics
+> for private formals and when deriving from a private type whose full
 > type is a record type?
 
-Hmmm.  The above doesn't really talk about a type *derived* from a private type.  In
-fact, I'm not sure the term "full type" is well defined for a type derived from a
-private type.  One model of a private type is that it is somewhat like a record type
-with the full type as its component type.  This would perhaps argue for making the
-primitive equality of any private type "composable." The tricky thing there is that
-you would get a different answer about composability depending on the "view" of the
-type.  That can't be good.  We really want composability to be a view-independent
-feature of the type.
-
-On the other hand, privacy argues that if you derive from a private type and there
-is no place within the immediate scope of the derivative where the parent type is
-non-private, then it should/could be treated as though it *might* be a record type,
-and any overriding of equality must satisfy the rules for a record type, and
-becomes composable.  This would apply within a generic body with a formal private
-type, where deriving from it could presume it *was* a record type, with composability
-provided to overridings of the equality operator.  Derivatives in the spec would
-follow the rules associated with the actual type, since we want all views of the
-derived type to follow the same rules.
-
-Alternatively, we could say that any derivative of a private type must follow the
-restrictions that apply to record types, namely no "late" or "private" overrides
-of equality, but that composability is only provided if the type is a record type
-"deep down." This alternative seems simpler.
-
-To summarize: composability is a dynamic semantics property and sees through privacy,
-applying to types whose "underlying" type is a record type. The legality restrictions
-on overriding "=" presume the worst, namely that when you don't have the full view
-of a private type then presume it *might* be a record type (even though you don't
-actually get any "benefit" from the restrictions unless the type is *really* a
-record type).
-
-This would ensure that only record types would have different dynamic semantics, and
-that *if* the equality operator is composable, it is the only equality operator that
-ever applies to the (record) type.
+Hmmm.  The above doesn't really talk about a type *derived* from a private type.
+In fact, I'm not sure the term "full type" is well defined for a type derived
+from a private type.  One model of a private type is that it is somewhat like a
+record type with the full type as its component type.  This would perhaps argue
+for making the primitive equality of any private type "composable." The tricky
+thing there is that you would get a different answer about composability
+depending on the "view" of the type.  That can't be good.  We really want
+composability to be a view-independent feature of the type.
+
+On the other hand, privacy argues that if you derive from a private type and
+there is no place within the immediate scope of the derivative where the parent
+type is non-private, then it should/could be treated as though it *might* be a
+record type, and any overriding of equality must satisfy the rules for a record
+type, and becomes composable.  This would apply within a generic body with a
+formal private type, where deriving from it could presume it *was* a record
+type, with composability provided to overridings of the equality operator.
+Derivatives in the spec would follow the rules associated with the actual type,
+since we want all views of the derived type to follow the same rules.
+
+Alternatively, we could say that any derivative of a private type must follow
+the restrictions that apply to record types, namely no "late" or "private"
+overrides of equality, but that composability is only provided if the type is a
+record type "deep down." This alternative seems simpler.
+
+To summarize: composability is a dynamic semantics property and sees through
+privacy, applying to types whose "underlying" type is a record type. The
+legality restrictions on overriding "=" presume the worst, namely that when you
+don't have the full view of a private type then presume it *might* be a record
+type (even though you don't actually get any "benefit" from the restrictions
+unless the type is *really* a record type).
+
+This would ensure that only record types would have different dynamic semantics,
+and that *if* the equality operator is composable, it is the only equality
+operator that ever applies to the (record) type.
 
 ****************************************************************
 
 From: Steve Baird
 Sent: Tuesday, December 9, 2008  1:48 AM
 
-So we get a change in the dynamic semantics of predefined equality operators and a
-legality rule prohibiting "late" user-defined equality operators in some cases.
+So we get a change in the dynamic semantics of predefined equality operators and
+a legality rule prohibiting "late" user-defined equality operators in some
+cases.
+
+It seems like we need other changes as well if you still want to treat
+squirreling renames and abstract equality operators as they were discussed in
+earlier posts.
 
-It seems like we need other changes as well if you still want to treat squirreling
-renames and abstract equality operators as they were discussed in earlier posts.
-
 What is your current thinking about these issues?
 
-I'm just trying to understand the full extent of this AI without glossing over any
-details.
+I'm just trying to understand the full extent of this AI without glossing over
+any details.
 
 ****************************************************************
 
@@ -2008,16 +2040,17 @@
 Sent: Tuesday, December 9, 2008  8:20 AM
 
 I think we still want squirreling via renames and require overriding or inherit
-abstractness, as appropriate, if a component has an abstract, composable, equality.
-I presumed that was independent of these other legality issues, but perhaps not...
+abstractness, as appropriate, if a component has an abstract, composable,
+equality. I presumed that was independent of these other legality issues, but
+perhaps not...
 
 ****************************************************************
 
 From: Steve Baird
 Sent: Tuesday, December 9, 2008  9:26 AM
 
-I was thinking about an interaction between the rule you described for the predefined
-equality operator of a private type and squirreling renames.
+I was thinking about an interaction between the rule you described for the
+predefined equality operator of a private type and squirreling renames.
 
 In this example,
 
@@ -2031,8 +2064,8 @@
         function "=" (L, R : T) return Boolean;
     end Pkg;
 
-we have decided that a call to Eq2 should not invoke the user-defined "=" operator. What
-about a call to Eq1?
+we have decided that a call to Eq2 should not invoke the user-defined "="
+operator. What about a call to Eq1?
 
 ****************************************************************
 
@@ -2041,22 +2074,25 @@
 
 I would hope we get the same answer if we add "tagged"
 to the record declaration.  One key goal is to make tagged and untagged records work
-the same way, at least with respect to equality, so there are fewer perverse incentives
-to make a record type tagged just so that it "works right."  I really don't want us to
-end up in a situation where tagged record equality works one way, untagged record
-equality works a second way, and non-record equality works a third way.
-
-I realize tagged types have private extensions, which don't really have an analogy
-in the non-tagged world, but hopefully untagged derivation would work very much like
-null tagged record extensions with respect to equality, whether the parent type is a
-visible record type or a private type whose full type is a record type.
+the same way, at least with respect to equality, so there are fewer perverse
+incentives to make a record type tagged just so that it "works right."  I really
+don't want us to end up in a situation where tagged record equality works one
+way, untagged record equality works a second way, and non-record equality works
+a third way.
+
+I realize tagged types have private extensions, which don't really have an
+analogy in the non-tagged world, but hopefully untagged derivation would work
+very much like null tagged record extensions with respect to equality, whether
+the parent type is a visible record type or a private type whose full type is a
+record type.
 
 ****************************************************************
 
 From: Steve Baird
 Sent: Friday, March 20, 2009  7:40 PM
 
-In Thursday's conference call, it was decided that I should attempt wording for AI05-0123.
+In Thursday's conference call, it was decided that I should attempt wording for
+AI05-0123.
 
 The result of that decision is attached. [This is version /04 of the
 AI - ED]
@@ -2067,7 +2103,7 @@
 Sent: Friday, March 20, 2009  9:15 PM
 
 >formatting error (wrong font, bad indentation) for
->#2 in the "These cases are dealt with as follows" list, starting with 
+>#2 in the "These cases are dealt with as follows" list, starting with
 >"type may not be declared".
 
 Well, the formatting of the on-line viewer isn't technically part of an AI,
@@ -2109,7 +2145,7 @@
 >      end Inner;
 >    end P;
 >
->We want to reject this example, but it's not clear what rule needs to 
+>We want to reject this example, but it's not clear what rule needs to
 >be invented to handle this case.
 
 Shouldn't we simply make the declaration of "=" illegal by analog with
@@ -2126,8 +2162,8 @@
 simplify the wording any to extend this to all composite types. (I doubt it
 would make it longer, but I don't see any simplifications, either.)
 
-I think your argument boils down to "anyone that redefines "=" without redefining
-"<=" compatibly is nuts, so we don't care what happens to them".
+I think your argument boils down to "anyone that redefines "=" without
+redefining "<=" compatibly is nuts, so we don't care what happens to them".
 Maybe that's OK.
 
 ****************************************************************
@@ -2138,13 +2174,13 @@
  > Steve: Make a new draft of AI-123.
 
 I did this and the writeup reflects the discussions of the group.
-However, it seems to me that the measures we are taking to statically prevent the
-invocation of an abstract equality operator are not worth the cost.
+However, it seems to me that the measures we are taking to statically prevent
+the invocation of an abstract equality operator are not worth the cost.
 
-How about a change in dynamic semantics so that this case may be allowed to occur
-(at least in some cases) and has well-defined dynamic semantics? If we want to, we
-could still statically reject the cases where we know precisely what is going on,
-as opposed to imposing assume-the-worst rules.
+How about a change in dynamic semantics so that this case may be allowed to
+occur (at least in some cases) and has well-defined dynamic semantics? If we
+want to, we could still statically reject the cases where we know precisely what
+is going on, as opposed to imposing assume-the-worst rules.
 
 Alternatives include
    - for purposes of deciding whether an untagged unlimited
@@ -2155,8 +2191,8 @@
    - raise Program_Error at the point where an abstract
      equality operation would otherwise be invoked.
 
-I would favor the latter because presumably the user had a good reason for declaring
-the equality operator to be abstract.
+I would favor the latter because presumably the user had a good reason for
+declaring the equality operator to be abstract.
 
 ****************************************************************
 
@@ -2165,10 +2201,10 @@
 
 I would be in favor of the second, since it seems like a better alternative than
 adopting a mess of incompatible and weird assume-the-worst static rules. Indeed,
-I've tried to make the suggestion on considering dynamic rules several times in the
-past without much interest. Perhaps you need to write up an alternative set of rules
-so we can see whether it helps any to do that. (I think squirreling renames still
-would be a problem, for instance.)
+I've tried to make the suggestion on considering dynamic rules several times in
+the past without much interest. Perhaps you need to write up an alternative set
+of rules so we can see whether it helps any to do that. (I think squirreling
+renames still would be a problem, for instance.)
 
 ****************************************************************
 
@@ -2179,8 +2215,242 @@
 > Should this whole AI should be abandoned?
 
 I (reluctantly) think so.  I say "reluctantly", since I was originally strongly
-in favor of this, but now I see it's getting out of hand.  It's just not worth it.
-At this point, I think the cure is indeed worse than the disease.
+in favor of this, but now I see it's getting out of hand.  It's just not worth
+it. At this point, I think the cure is indeed worse than the disease.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, June 29, 2009  11:05 PM
+
+I'm updating AI-123 for our meeting notes, and I think the wording Steve
+proposed is ambiguous. Each time I read, the more ambiguous it appears.
+
+In several places, he replaced "tagged" with "record" thus:
+
+  For a type extension, predefined equality is defined in terms of the
+  primitive [(possibly user-defined)] equals operator of the parent type
+  and of any {record}[tagged] components of the extension part, and predefined
+  equality for any other components not inherited from the parent type.
+
+The problem here is that "record components" has a well-used meaning which is
+definitely not what Steve means here. Indeed, all components of an extension
+part are "record components". He really means "components of a record type", and
+we ought to say that here:
+
+  For a type extension, predefined equality is defined in terms of the
+  primitive [(possibly user-defined)] equals operator of the parent type
+  and of any [tagged] components {of a record type} of the extension part,
+  and predefined equality for any other components not inherited from
+  the parent type.
+
+This is a bit annoying because of the two "ofs", but at least it isn't
+ambiguous.
+
+The other wording is even more ambiguous:
+
+* Otherwise, the result is defined in terms of the primitive equals operator
+  for any matching record components, and the predefined equals for any
+  other matching components.
+
+Ugh: even knowing what is meant, I still think this means that you use the
+primitive equals for all components of a record, and the predefined equals for
+the components any other kind of composite object. Adam will be all over us!
+
+Unfortunately, the simple fix doesn't seem to work:
+
+* Otherwise, the result is defined in terms of the primitive equals operator for
+  any matching components of a record type, and the predefined equals for any
+  other matching components.
+
+It's still not completely clear. (I note that the original wording was also
+ambiguous this way. Where's Adam?? ;-)
+
+* Otherwise, the result is defined in terms of the primitive equals operator for
+  any matching components that have a record type, and the predefined equals for
+  any other matching components.
+
+Seems to work, but it's a bit awkward.
+
+Better wording is requested.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, June 29, 2009  11:16 PM
+
+> * Otherwise, the result is defined in terms of the primitive equals operator
+>   for any matching components that have a record type, and the predefined equals for any
+>   other matching components.
+>
+> Seems to work, but it's a bit awkward.
+
+I just found an AARM note (that I need to change) that uses "with":
+
+ * Otherwise, the result is defined in terms of the primitive equals operator
+   for any matching components with a record type, and the predefined equals for
+   any other matching components.
+
+That seems better to me.
 
 ****************************************************************
 
+From: Tucker Taft
+Sent: Monday, June 29, 2009  11:16 PM
+
+...
+>   For a type extension, predefined equality is defined in terms of the
+>   primitive [(possibly user-defined)] equals operator of the parent type
+>   and of any [tagged] components {of a record type} of the extension part,
+>   and predefined equality for any other components not inherited from
+>   the parent type.
+
+Perhaps change some of the "of"s to "for" or "in":
+
+   For a type extension, predefined equality is defined in terms of the
+   primitive [(possibly user-defined)] equals operator for the parent type
+   and for any [tagged] components {of a record type} in the extension part,
+   and predefined equality for any other components not inherited from
+   the parent type.
+
+...
+> * Otherwise, the result is defined in terms of the primitive equals operator
+>   for any matching components that have a record type, and the
+> predefined equals for any
+>   other matching components.
+>
+> Seems to work, but it's a bit awkward.
+
+Perhaps:
+
+* Otherwise, the result is defined in terms of the primitive
+   equals operator for any matching components that are records,
+   and the predefined equals for any other matching components.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, June 29, 2009  11:47 PM
+
+This AI has:
+
+Append after 8.5.4(7.1/1)
+
+  A corresponding rule applies to a call on a renaming of
+  a predefined equality operator for an untagged record type
+  that is overridden if the overriding occurs after the renaming.
+
+This doesn't make any sense to me; 8.5.4(7.1/1) is about renames-as-body, which
+has nothing to do with squirrelly renames. (Umm, squirreling renames).
+
+The very next paragraph is about renames of dispatching calls, which is the
+analogy that we are trying to preserve:
+
+  For a call on a renaming of a dispatching subprogram that is overridden,
+  if the overriding occurred before the renaming, then the body executed
+  is that of the overriding declaration, even if the overriding declaration
+  is not visible at the place of the renaming; otherwise, the inherited or
+  predefined subprogram is called.
+
+Note that this is about *statically* bound calls to dispatching routines;
+because if they are dispatching calls, the body called is determined dynamically
+and has nothing to do with this text. So it is perfectly appropriate here; all
+we need to add to this is
+
+  A corresponding rule applies to a call on a renaming of
+  a predefined equality operator for an untagged record type.
+
+And we're done.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, June 30, 2009  12:32 AM
+
+I am wondering how we are preventing reemergence for derived untagged record
+types. We prevent it for tagged types by defining that "predefined equality" is
+depends on the primitive equality for the parent type and that of extension
+components. We also have a rule for private types (which now applies to all
+record types).
+
+But I think we need a similar rule for untagged derived types. If we don't have
+one, we drop out to 4.5.2(16), and that uses the component-by-component equality
+to define "predefined equality".
+
+Note that the inherited equality is *not* the predefined equality (it is
+primitive, but not predefined).
+
+So I think we need some wording like:
+
+For a derived type whose parent is an untagged record type, predefined equality
+is defined in terms of the primitive (possibly user-defined) equals operator of
+the parent type.
+
+This should follow 4.5.2(15).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, June 30, 2009  9:26 AM
+
+Good point.  I agree with your logic and your solution.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Monday, June 30, 2009  9:35 AM
+
+...
+>   For a type extension, predefined equality is defined in terms of the
+>   primitive [(possibly user-defined)] equals operator of the parent type
+>   and of any [tagged] components {of a record type} of the extension part,
+>   and predefined equality for any other components not inherited from
+>   the parent type.
+> 
+> This is a bit annoying because of the two "ofs", but at least it isn't 
+> ambiguous.
+
+I agree that this is an improvement.
+
+> The other wording is even more ambiguous:
+> 
+> * Otherwise, the result is defined in terms of the primitive equals operator
+>   for any matching record components, and the predefined equals for any
+>   other matching components.
+> 
+
+> 
+> * Otherwise, the result is defined in terms of the primitive equals operator
+>   for any matching components that have a record type, and the 
+> predefined equals for any
+>   other matching components.
+> 
+> Seems to work, but it's a bit awkward.
+> 
+> Better wording is requested.
+
+This seems adequate. As you noted. you really need "components that have a record type",
+as opposed to "components of a record type".
+
+Good catches!
+
+****************************************************************
+
+From: Ed Schonberg
+Sent: Monday, June 30, 2009  10:39 AM
+
+> I just found an AARM note (that I need to change) that uses "with":
+
+> * Otherwise, the result is defined in terms of the primitive equals operator
+>   for any matching components with a record type, and the predefined equals
+>   for any other matching components.
+>
+> That seems better to me.
+
+I have a slight preference for
+
+    any matching components that are of a record type
+or
+   any matching components that have a record type
+
+****************************************************************

Questions? Ask the ACAA Technical Agent