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

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

--- ai05s/ai05-0123-1.txt	2008/10/19 01:29:16	1.1
+++ ai05s/ai05-0123-1.txt	2008/10/25 04:53:14	1.2
@@ -247,3 +247,884 @@
  
 ****************************************************************
 
+From: John Barnes
+Sent: Monday, October 20, 2008  11:21 AM
+
+Can I bring up the equality business again?
+
+Much of the traffic on this topic has been about the problems of fuzzy
+floats. The original example in the proposed AI was therefore unfortunate
+by confusing the issue. It was about the general desire to control
+composability and not meant to be about fooling around with floating
+equality per se.
+
+Below is another example not involving floats. It has two types Doctor_Type
+and Appointment_Type. Both have equality redefined to ignore certain
+components of the type. It then introduces a type Appointment hoping
+that this type would use the redefined equality for the components but
+it doesn't.
+
+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. 
+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
+has not been messed about with?
+
+---
+
+with Ada.Calendar; use Ada.Calendar;
+with Ada.Text_IO;
+with Ada.Integer_Text_IO;
+procedure Compose is
+
+   type Doctor_Type is record
+    Name     : string (1..20) := "Unknown             ";
+    Comments : string (1..20);
+   end record;
+
+   function "=" (Left, Right : Doctor_Type) return Boolean is
+   begin
+      if Left.Name = Right.Name then
+         return True;
+      else
+         return False;
+      end if;
+   end "=";
+
+
+   type Patient_Type is record
+    Name     : string (1..20) := "Unknown             ";
+    Comments : string (1..20);
+   end record;
+
+   function "=" (Left, Right : Patient_Type) return Boolean is
+   begin
+      if Left.Name = Right.Name then
+         return True;
+      else
+         return False;
+      end if;
+   end "=";
+
+   type Appointment_Type is record
+      Doctor  : Doctor_Type;
+      Patient : Patient_Type;
+      Date    : Time;
+   end record;
+
+   Appointment_1 : constant Appointment_Type := (
+                         Doctor  => (Name     => "Oliver Cousins      ",
+                                     Comments => "Neurologist         "),
+                         Patient => (Name     => "Amy Cole            ",
+                                     Comments => "Always late         "),
+                         Date    => Time_Of (Year  => 1988,
+                                             Month => 8,
+                                             Day   => 8));
+
+   Appointment_2 : constant Appointment_Type := (
+                         Doctor  => (Name     => "Oliver Cousins      ",
+                                     Comments => "Nerve specialist    "),
+                         Patient => (Name     => "Amy Cole            ",
+                                     Comments => "Late again          "),
+                         Date    => Time_Of (Year  => 1988,
+                                             Month => 8,
+                                             Day   => 8));
+
+begin
+   Ada.Text_IO.Put_Line ("Doctors");
+   Ada.Text_IO.Put (Appointment_1.Doctor.Name);
+   Ada.Text_IO.New_Line;
+   Ada.Text_IO.Put_Line ("and");
+   Ada.Text_IO.Put (Appointment_2.Doctor.Name);
+   Ada.Text_IO.New_Line;
+   Ada.Text_IO.Put ("are ");
+
+   if Appointment_1.Doctor = Appointment_2.Doctor then
+      Ada.Text_IO.Put_Line ("the same");
+   else
+      Ada.Text_IO.Put_Line ("different");
+   end if;
+
+   Ada.Text_IO.Put_Line ("Patients");
+   Ada.Text_IO.Put (Appointment_1.Patient.Name);
+   Ada.Text_IO.New_Line;
+   Ada.Text_IO.Put_Line ("and");
+   Ada.Text_IO.Put (Appointment_2.Patient.Name);
+   Ada.Text_IO.New_Line;
+   Ada.Text_IO.Put ("are ");
+
+   if Appointment_1.Patient = Appointment_2.Patient then
+      Ada.Text_IO.Put_Line ("the same");
+   else
+      Ada.Text_IO.Put_Line ("different");
+   end if;
+
+   Ada.Text_IO.Put_Line ("Appointments");
+   Ada.Text_IO.Put (Appointment_1.Doctor.Name);
+   Ada.Text_IO.Put (' ');
+   Ada.Text_IO.Put (Appointment_1.Patient.Name);
+   Ada.Text_IO.Put (' ');
+   Ada.Integer_Text_IO.Put (Year (Appointment_1.Date));
+   Ada.Text_IO.Put (' ');
+   Ada.Integer_Text_IO.Put (Month (Appointment_1.Date));
+   Ada.Text_IO.Put (' ');
+   Ada.Integer_Text_IO.Put (Day (Appointment_1.Date));
+   Ada.Text_IO.New_Line;
+
+   Ada.Text_IO.Put_Line ("and");
+
+   Ada.Text_IO.Put (Appointment_2.Doctor.Name);
+   Ada.Text_IO.Put (' ');
+   Ada.Text_IO.Put (Appointment_2.Patient.Name);
+   Ada.Text_IO.Put (' ');
+   Ada.Integer_Text_IO.Put (Year (Appointment_2.Date));
+   Ada.Text_IO.Put (' ');
+   Ada.Integer_Text_IO.Put (Month (Appointment_2.Date));
+   Ada.Text_IO.Put (' ');
+   Ada.Integer_Text_IO.Put (Day (Appointment_2.Date));
+   Ada.Text_IO.New_Line;
+   Ada.Text_IO.Put ("are ");
+
+   if Appointment_1 = Appointment_2 then
+      Ada.Text_IO.Put_Line ("the same");
+   else
+      Ada.Text_IO.Put_Line ("different");
+   end if;
+
+end Compose;
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, October 20, 2008  11:34 AM
+
+I would be in favor of composable equality for all record types.
+Currently only tagged record types compose, and I think that we were
+just running scared of teeny incompatibilities in Ada 9x when we resisted
+extending that to cover all record types.  I agree with Pascal that making
+user-defined operators on numeric types "compose" is asking for trouble,
+but I don't see the problem for record types.  Upward compatibility would
+argue for a pragma, I suppose, but I would consider just doing it by fiat,
+and let the chips fall where they may.  I really can't imagine a case
+where you wouldn't want record-type equality to compose, but I suppose
+I am willing to hear about one.
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Monday, October 20, 2008  11:40 AM
+
+But then why exclude it for array types?
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, October 20, 2008  11:46 AM
+
+> I really can't imagine a case
+> where you wouldn't want record-type equality to compose, but I suppose
+> I am willing to hear about one.
+
+It's less an issue of an example that has some deliberate use of this
+misfeature, than worrying about mysterious incompatibilities for existing
+code.
+
+Ed, how about we instrument GNAT to see how many cases in our test suite
+would be affected by such a change
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, October 20, 2008  11:56 AM
+
+Array types are more difficult in my view.  You can convert between
+unrelated array types, and if the equality properties have to do with
+something other than the component type, that might imply some special
+situations with slices and/or sliding. I also worry that some array types
+have operations besides equality (<, >, and, or, etc.).  I am not
+excited about trying to define how those compose.
+
+Record types have at most one predefined operator that the user can
+override explicitly (yes, I know about "/=" ;-), and that makes them
+much simpler to deal with in my view.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, October 20, 2008  12:00 PM
+
+> But then why exclude it for array types?
+
+The problem (as I understand it) is that it is nearly impossible to write
+a correct generic if you cannot trust the relationships between the various
+relational operators. And there is no composition of other operators. That's
+not a problem for record types, because they don't have any other relational
+operators other than equality. But (some) array types do have the other
+ordering operators; since those don't compose, the same problem would occur
+for them.
+
+I suppose we could try to fix that problem by trying to figure out how
+composition of the other predefined operators ought to work, but it surely
+isn't as obvious as "=" is.
+
+****************************************************************
+
+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 
+> suite would be affected by such a change
+
+We could check on all uses of predefined equality on records for which
+some component has a user-defined equality. Is that what you have in mind?
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, October 20, 2008  12:28 PM
+
+yes, these are the cases where a change would make a difference
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, October 20, 2008  12:37 PM
+
+That would certainly be some relevant data.
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Monday, October 20, 2008   4:54 PM
+
+Preliminary results: out of some 11719 relevant tests in the suite,
+there are 23 that perform equality on a record that has some component
+for which there is an explicit equality. Most of them are records
+that contain an unbounded_string or an address.  I'll look at some
+of these to see whether proper composition would affect the results.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, October 20, 2008  5:05 PM
+
+But both of these types are required to have composable equality
+by the language definition (see RM 4.5.2(32.1/1)).
+
+Any other cases where the types aren't language defined types?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, October 20, 2008  5:07 PM
+
+For nonlimited language-defined types, the language requires that they
+compose properly (or act like it). See 4.5.2(31.1/1). So proper
+composition should not affect the results of either of those types
+(if it does, your compiler has a bug). A component would have to be a
+user-defined type in order for it to matter.
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Monday, October 20, 2008  5:40 PM
+
+> 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
+compiler did not special-case these types.
+
+> Any other cases where the types aren't language defined types?
+
+There are 6 tests with user-defined types, that I have to examine more
+closely.
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Monday, October 20, 2008  8:52 PM
+
+OK, there are 5 tests with equality on untagged record types that have
+components with user-defined equality. Of these:
+
+One is a query from a customer (many years ago) who was puzzled that
+equality did not compose.
+
+One of them is in GNAT code, and one of the operands is a constant that
+represents the null value for the type.  This works properly in this
+case but it's slightly suspicious, and would in fact be better if equality
+composed.
+
+One of them is in the expanded code for a generated equality routine
+with a subcomponent with user-defined equality.
+
+Two of them are in Inspector code, and I'm sure they are correct :-)!
+
+Conclusion from this small sample: having equality compose would be
+harmless, and of course clearer conceptually.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, October 20, 2008  9:14 PM
+
+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).
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Monday, October 20, 2008  11:10 PM
+
+Maybe we could just be extreme and declare that it was simply a typo
+that equality did not compose and we forgot to fix it in Ada 95 and
+Ada 2005 :-)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, October 20, 2008  11:49 PM
+
+That's tempting, but I think that the subtle incompatibility involved is
+best being associated with a major version change to the language. I recall
+someone else making the point that users are not likely to be surprised
+about incompatibilities when moving between major versions (like Ada 95 to
+Ada 2005), but are more likely to not be expecting changes when moving from
+GNATPro 6.2 to 6.2.1 (or some similar minor compiler change).
+
+The problem here is while we're pretty sure the change will fix more bugs
+than it introduces, there is likely to be that one big project that somehow
+managed to depend on this behavior.
+
+I suspect that it would be better to tie the change to Ada 2005 (if we're even
+that bold) or Ada 2014 (if we're not); that would have the advantage that
+projects with problems could at least regress to the Ada 95 semantics
+(presuming that most compilers have a way to get that).
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, October 21, 2008  8:17 AM
+
+Actually my view is that it is unacceptable to regard major version changes
+as a source of incompatibilities. If we think of this as an incompatibility
+that is only acceptable for a major version change, then it is not acceptable
+for that either. The Ada 2005 design introduced serious incompatibilities
+that are still causing trouble, and still acting as an impediment to adoption
+of Ada 2005.
+
+Users *ARE* surprised by significant incompatibilities between versions, and
+a *MAJOR* inducement to moving to a new version of the language is to guarantee
+that there are no such cases. Ada 2015 is very unlikely to have enough goodies
+to induce change ten years out to cancel out worries about incompatibilites.
+
+To me there are only two acceptable choices
+
+a) decide this is a fix, and that therefore it is not only acceptable but
+desirable to retrofit it to old versions. An implementor worried about the
+incompatibility issue can introduce a switch to maintain the old "wrong"
+behavior.
+
+b) decide that this is an incoimpatible change, in which case it is not
+acceptable unless triggered by a pragma, which should either be useable
+as a global configuration pragma, or be applicable to a specified type.
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Tuesday, October 21, 2008  8:59 AM
+
+Or maybe:
+c) decide that this is an incompatible but desirable change, with a
+    pragma to keep the *old* behaviour, for the  rare cases where there
+    is a serious compatibility issue.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, October 21, 2008  9:06 AM
+
+I would use a pragma for the new behavior. In new code wanting to use
+this feature, chucking in a pragma is no sweat, but telling people they
+have to modify existing code because of an incompatibilty we consider
+significant seems undesirable.
+
+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.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 21, 2008  9:32 AM
+
+The decision in Ada 9X about tagged versus untagged was connected to a
+number of relatively obscure technical issues.
+In general, we required overriding of an operation of a tagged type to
+be subtype conformant with the inherited operation, whereas Ada 83 only
+required "type conformance" for overriding of operations of an untagged
+type, which meant that even the modes of the parameters could differ.
+The overriding of predefined operators obviously couldn't have mode
+mismatches, since operators only allow IN parameters, but you could have
+different subtypes at the least, though why you would want to override
+with a more restrictive subtype is hard to imagine.
+We wanted to treat operators the same way we were treating the operations
+inherited from the ancestor type for a formal derived type, and we wanted
+composability and the rules for reemergence in generic instances to match
+up consistently.
+
+If we step back now and see where the biggest "surprise" is, I think
+predefined record-type equality "reemerging" in generics, and not composing
+properly, is the one that remains.  A surgical strike to eliminate that seems
+like a good idea in my mind, and leave the other differences between
+tagged and untagged types as they are.  And I guess I agree with Robert,
+this ought to be something that can be back-fitted to existing compilers.
+Unlike the Ada 83 to Ada 95 transition, I see people "slipping" into
+Ada 2005 features on a more incremental basis.  Containers are very
+attractive, and just getting them to compile either requires making
+various changes to them to get them back into Ada 95 acceptability, or
+starting to adopt at least some Ada 2005 features.
+
+I think in retrospect it *was* a mistake to distinguish between tagged
+and untagged record types as far as predefined equality, but it was hidden
+behind some bigger distinctions that I believe were *not* a mistake.
+
+A pragma is probably the right approach, but there is nothing saying that
+it couldn't be the "default" configuration to have the pragma already in
+place. Having a pragma that allows the user to specify either direction
+is probably safest, so that if you say nothing, you get the default
+behavior of the compiler (unless in ACATS mode of course where you get
+the standard behavior which at this point is no composition), and then
+you can specify either you want composition, or you rely on
+non-composability.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 21, 2008  10:01 AM
+
+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?
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, October 21, 2008  10:30 AM
+
+> 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?
+
+That's the really big one, can't remember any others that are causing
+continued grief, Bob?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 21, 2008  9:54 AM
+
+Gosh, I hate to say it, but this might argue for bringing back the idea
+of a "Features" pragma... ;-)
+
+The danger of having a single-purpose pragma for this is that if the
+compiler does *not* support the feature, you don't get an error, but
+instead just a warning that you have an unrecognized pragma.  If we add
+a general pragma that the compiler *must* support, such as "Restrictions,"
+and then require that it fail if it sees the name of a feature it doesn't
+recognize, we can give the user some comfort that if they are depending
+on the presence of some particular feature, they will get an error if the
+feature isn't supported.
+
+We could use "No_<blah>" and "<blah>" to indicate a requirement that the
+feature not be present, or that the feature be present.  E.g.:
+
+     pragma Features(No_Record_Equality_Composability);
+
+   vs.
+
+     pragma Features(Record_Equality_Composability);
+
+This pragma would cause an error if the feature name were not recognized.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, October 21, 2008  10:25 AM
+
+I think I would prefer
+
+    pragma Composable_Equality (On | Off);
+
+****************************************************************
+
+From: Joyce Tokar
+Sent: Tuesday, October 21, 2008  10:31 AM
+
+Why not update pragma Restrictions to achieve this goal?
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Tuesday, October 21, 2008  10:43 AM
+
+this really has nothing to do with a restriction, and I don't see a
+way of recasting it in that mode, do you? Joyce?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 21, 2008  11:05 PM
+
+Composable_Equality is going a bit too far, since I don't think we
+want to imply that we will do this for non-record types.
+
+You didn't comment on my point about recognizable pragmas -- that is
+we want the user to be sure the pragma isn't just being ignored. I
+also worry about a proliferation of special-purpose pragmas.  Eventually
+you want to be able to have a single place where you define what is
+the set of features you are using.
+
+With a pragma like "Features" and the existing "Restrictions," we could
+have a pair of pragmas that pretty much define what is acceptable.  If
+we define a collection of possibly overlapping feature/restriction-ish
+pragmas, really knowing what features are safely usable in a given
+program may be tricky.  When combined with the notion of a Profile,
+we could get a nice triumvirate.
+
+****************************************************************
+
+From: Joyce Tokar
+Sent: Tuesday, October 21, 2008  11:48 AM
+
+Essentially, this is what I was driving at with my question about
+pragma Restrictions --- and we know about restriction profile --
+see Ravenscar.
+
+****************************************************************
+From: Robert Dewar
+Sent: Tuesday, October 21, 2008  11:26 AM
+
+What are other features you have in mind for this pragma, a pragma
+with only one possibility seems silly to me.
+
+what existing pragams could be subsumed,
+
+also we want this pragma to be able to apply to a specific type,
+how would that fit into your scheme.
+
+I don't see any problem in proliferation, we have hundreds of pragmas
+already!
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, October 21, 2008  12:00 PM
+
+I had imagined using a pragma Features for the various Ada 2005 features
+which might be provided "piecemeal."
+I suppose it would be most important for features that involve any kind
+of potential semantic inconsistency, such as the return-by-reference vs.
+build-in-place, but it could be useful as documentation for the set of
+features expected to be fully supported.  The danger is that some compiler
+might accept the syntax for something like access-to-subprogram, but not
+support the full downward closure semantics.
+
+Or more obviously, whether null values can be passed to access parameters
+might not be at all obvious, because we have encouraged Ada 95 compilers
+to accept, and ignore, the "not null" syntax on access parameters.  I can
+see the same thing effectively happening with, say "private with,"
+where the compiler would be augmented to accept the syntax, but treat it
+as equivalent to simply "with."  This is most tempting when trying to
+compile the container packages, where you might be able to get away with
+accepting the Ada 2005 syntax they use, but "punt" on the semantics where
+possible.
+
+I know I was tempted by that recently, because the latest GNAT sources
+use container packages, and I was trying to compile them with AdaMagic to
+host the gnat2scil on my laptop in the absence of a GNAT version for
+Mac OS X that could compile the inspector.
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Tuesday, October 21, 2008  12:06 PM
+
+>> 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 certainty of portability in this area).
+
+Indeed, no ACATS tests (either B or C) that have a comparison of
+untagged records with a component that has a user-defined equality.
+Given the state of this discussion, you might not want to rush and
+add this to the test objectives of ACATS 3X :-)!
+
+****************************************************************
+
+From: Robert I. Eachus
+Sent: Tuesday, October 21, 2008  1:46 PM
+
+I think the idea of a pragma is best.  That way with a wink an a nod,
+the default behavoir for compilers can be equality always composing in
+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.. 
+(Only needed of course, if you define an equality operation for a type.)
+
+pragma Equality_Composes( For => Base_Type); --seems right, with
+                 -- no argument can be used as a configuration pragma.
+
+The other way is harder:
+
+pragma Equality_Does_Not_Compose(For => Base_Type); --seems wordy, and still not correct.
+pragma Predefined_Equality_Reemerges(For => Base_Type); --not as scary for the uninitiated...
+
+Any better suggestions?  It would be nice to have something that looks
+appropriate for Boolean.
+
+
+****************************************************************
+
+From: Randy Brukardt
+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 
+> silly to me.
+
+I was hoping to answer this question, since I was wondering about that
+myself. Tucker has answered why tagged types are different, but the more
+interesting question is why Ada 83 adopted non-composition in the
+first place. However, none of the on-line materials (such as the Ada 83
+Rationale) say anything about equality at all (so the smaller question of
+composition isn't answered either). I could speculate (This issue was never
+really considered? a misguided attempt to reduce implementation complexity?
+A worry about consistency of relational operations?) but that doesn't do
+any good.
+
+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.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Wednesday, October 22, 2008  8:21 PM
+
+And as I noted, you can't in general do block compares because of float values
+*anyway*, so the whole thing seems bogus
+
+It is interesting that several of the cases we found in our test suite were
+in our internal code, and in all cases, the author was VERY surprised and
+we had latent bugs.
+
+I more and more think we should do the following
+
+a) fix the bug, for all versions of Ada
+
+b) note that implementors may wish to provide a pragma to rever to the old
+state of the language. We can suggest the form of this pragma, but I see
+no reason to have it be part of the formal definition of Ada.
+
+I don't believe there could be any real compatibility problems in practice,
+on the contrary I think it is likely this will fix bugs!
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, October 22, 2008  9:35 PM
+
+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 connection between equality and assignment.
+
+****************************************************************
+
+From: Robert I. Eachus
+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 
+>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,
+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.  But there was a lot of hardware around
+in the early eighties with non-IEEE formats, and some allowed mixing
+unnormalized and normalized values.  The hardware did the floating point
+compares right--but  the existence of an FP field in a record on such
+hardware meant you couldn't use a bitwise compare.
+
+The issues of implementing equality when there were unused or uninitialized
+bits in a record, didn't really emerge until after Ada 83 was in its final
+form.  There was a similar implementation issue that showed up with the
+80286.  You could have pointers--excuse me access values--that designated
+the same object which were not bit for bit identical.  I don't think this
+ever got resolved as such, since the 80386 encouraged, instead, the use of
+a 32-bit flat address space.  (You could ask Alsys how their '286 compiler
+dealt with that.  My guess is that the compiler only created one designation
+for a heap object, and other equivalent pointer values were treated as
+non-identical.)  There was also an issue with the Motorola 860x0 family
+addresses.  They were technically 36-bit addresses, and the 16 address spaces
+could point at different views of the same memory.  However, AFAIK, this
+feature was only used during boot up. The boot PROM was usually given its
+own address space, then mapped above the RAM once virtual memory was
+activated.  AFAIK no 680x0 OS ever supported more than 32-bit addressing.
+(I remember the 36-bit address details mostly because of changes between
+the 68020 and 68030 in this area.  I updated the Stratus assembler to
+support 68030 chips, and at least half the work involved addressing modes
+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. 
+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
+Unchecked_Conversion! ;-) for all but a few bytes, because the compiler
+generated code was so slow in, I think, Verdix 4.1.  Anyway when he showed
+the results to Verdix, they incorporated his code into the compiler.
+(After asking permission, and Dave publishing the code in a paper to
+handle the rights issues. ;-)
+
+****************************************************************
+
+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 
+> formats have a single valid representation for every value--at least within types.
+
+not true, +0.0 and =0.0 must compare equal!
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, October 23, 2008  7:12 PM
+
+> 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 
+> connection between equality and assignment.
+
+Well, obviously that wasn't true in practice (the Goodenough trick was widely
+known and used to redefine non-limited "="), but I suppose it explains why
+the issue wasn't seriously considered. But that then begs the question of
+why you didn't just fix it in Ada 95 (any existing code would have had to
+have been on the margins of the language) as opposed to leaving it broken
+so that now it is far more likely to have occurred in practice. I suppose
+compatibility concerns were brought up then, too, and you were very sensitive
+to this kind of incompatibility.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, October 23, 2008  7:20 PM
+
+This reminds me a little of the Fortran discussion. In old Fortran, DO loops
+always traveled at least one even if the high bound was less than the low bound.
+
+This was ugly, and the Fortran committee wondered whether to change it.
+They did an extensive survey and found one case where it mattered, and it was
+a bug!
+
+Similarly, our survey of existing code found only a couple of cases where it
+mattered, and one was a latent bug, where the author thought it composed, but
+luckily it happened to work anyway, and other was a real bug, where the author
+thought it composed, and the fact that it didn't was a real bug.
+
+Based on that I think we should do what the Fortran commmittee decided to do
+ .. fix the bug!
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, October 23, 2008  7:21 PM
+
+Note incidentally that I am normally in a mode of being fanatic about
+avoiding upward incompatibilities, so I am giving my thoughts on this
+issue in light of that basic attitude.
+
+****************************************************************
+
+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. ;-)
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, October 23, 2008  7:44 PM
+
+Well compatibility is a pragmatic issue not a theoretical issue, so the issue
+is will existing customers be affected? Sometimes we make changes (like 'Size
+in Ada 95, which are not theoretically compatibility issues, but are in
+practice). When we make inncompatibloe changes, the issue is not whether there
+exist probels in theory, but whether these problems exist in practice.
+
+As Yogi Berra said, In theory, practice and theory are the same, in practice
+they are different.
+
+****************************************************************
+
+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 
+> > 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!
+
+Not to mention that it doesn't work for one's complement Integers (as we found
+out on the U2200 - +0 and -0 had better compare equal) nor for records with
+holes (you could initialize the holes to zero, but record object creation is
+much more likely than record comparison - at least in the code we looked at -
+so optimizing the less likely operation doesn't make much sense). The idea that
+you can alway use a bit comparison is bogus. You can use bit comparisons in
+some cases (it is worth optimizing them to bit string comparisons, and in fact
+we did so from day one), but you can't do so much of the time. It's much the
+same as streaming in that sense (there is a lot of value to bit streaming of
+a record, but you can only do it in limited cases).
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Thursday, October 23, 2008  7:42 PM
+
+Right, so compilers already almost certainly have the needed circuitry.
+I know that in GNAT this would be a VERY easy change to make, probably
+a line or two.
+
+****************************************************************

Questions? Ask the ACAA Technical Agent