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

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

--- ai05s/ai05-0096-1.txt	2008/05/24 03:19:29	1.1
+++ ai05s/ai05-0096-1.txt	2008/05/29 01:41:25	1.2
@@ -1,4 +1,5 @@
-!standard 3.4(5.1/2)                                     08-05-23  AI05-0096-1/01
+!standard 3.4(5.1/2)                                     08-05-28  AI05-0096-1/02
+!standard 6.2(7)
 !class binding interpretation 08-05-23
 !status work item 08-05-23
 !status received 06-05-21
@@ -12,6 +13,8 @@
 An instance of a generic is illegal if a limited type extension is derived from
 a formal tagged limited private type and the actual type is nonlimited.
 
+Derivation does not change the by-reference or by-copy status of a type.
+
 !question
 
 Consider the following:
@@ -51,6 +54,12 @@
 to prevent that in the private part (type extension from a formal type is illegal
 in a generic package body).
 
+Replace 6.2(7) by:
+
+ * an explicitly limited record type;
+
+Move the Ramification 6.2(7.a) after the bulleted list.
+
 !discussion
 
 As explained by AARM 3.4(5.b-f/2), 3.4(5/2) is one of the (very few) rules
@@ -71,13 +80,53 @@
 tagged type.
 
 So it seems that the example in the question should also be allowed for
-similar reasons.
+similar reasons. Note that the alternative would be to disallow most
+limited derivations (even for untagged types) in bodies, which seems too
+severe a restriction.
 
 However, this is not true if the parent type is known to be a tagged type,
 because then we could pass a value of New_Lim to the class-wide type
 corresponding to the parent type. If that parent type is also nonlimited,
 we could then assign a limited tagged type.
 
+An objection was raised to this intepretation noting that a limited derived
+type is covered by 6.2(7), and thus such a type would be a by-reference type.
+That appears to be a problem if the actual type is by-copy; it surely cannot
+be both.
+
+However, it is not specifically a problem with this case, but rather a general
+problem with the definition of by-reference types -- derived types should never
+change the parameter passing kind. For instance, consider:
+
+    package P is
+       type LP is limited private;
+       procedure Prim (Param : in LP);
+    private
+       type LP is new Integer;
+    end P;
+
+LP surely is a by-copy type (by 6.2(3)), so Param is passed by copy. Now
+make a non-generic package:
+
+    with P;
+    package Q is
+       type New_LP is new P.LP;
+    end Q;
+
+6.2(7) says that New_LP is a by-reference type; thus a call on the inherited
+Prim should pass Param by-reference. But the parent routine is by-copy, and
+it isn't possible to have the effect of pass-by-reference for Param. (Even a
+wrapper would have to copy Param; the only way to do it would be to duplicate
+the body of Prim, which is clear insanity.)
+
+It's clear that this definition was not updated when limited derived types were
+introduced late in the Amendment process. An investigation of the standard shows
+that the reserved word "limited" is used only in a few places: private types and
+formal private types (already excluded by 6.2(7)), derived types and formal
+derived types (the incorrect case that we want to exclude from 6.2(7)), limited
+with clauses (irrelevant here), limited interfaces (covered by 6.2(5), so they
+don't need to be covered by 6.2(7)), and explicitly limited record types.
+
 --!corrigendum 3.4(5.1/2)
 
 !ACATS Test
@@ -199,6 +248,284 @@
 nonlimited because the rules of 3.9.1 are rechecked), so we have a special rule
 to prevent that in the private part (type extension from a formal type is illegal
 in a generic package body).
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Saturday, May 24, 2008  3:13 AM
+
+> It seems that the same thinking should apply to this declaration: there is
+> no location where New_Lim could ever be seen as a non-limited type. So there
+> doesn't seem to be a problem. Similarly in the body.
+
+Not so fast.
+
+First, it is very weird in this case too: reserved words should not lie.
+One of the good things about "limited" in a type derivation is that it
+improves readability and maintainability: if the parent type is changed to
+become nonlimited, you hear about it.  This seems to apply in generics
+as well as in non-generic code.
+
+More importantly, you've got to explain what the parameter passing mode is
+for New_Gen.New_Lim.  6.2(3) says that it's by-copy ('cause it's elementary)
+and 6.2(7) says that it's by-reference ('cause it has "limited").  Are you
+sure you want to force implementers to support by-reference integer types?
+I don't think so. And tweaking the rules in 6.2 so prevent New_Gen.New_Lim
+from being considered by-reference seems unwise to me: it would be a lot of
+work and it could easily break things.
+
+So again, I am arguing in favor of rechecking in the private part, and of
+an assume-the-worst rule in the body.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Saturday, May 24, 2008  7:52 AM
+
+Your point about parameter passing doesn't really fly, since the actual
+could itself be a limited private type, but still be pass-by-copy.
+I certainly don't understand the value of specifying assume-the-worst
+in the body.
+
+I don't see any harm in allowing this in the private part, presuming the type
+is in fact treated like a limited private type whose full type might be
+non-limited.
+
+Or am I missing something fundamental?
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Sunday, May 235 2008  3:16 AM
+
+> Or am I missing something fundamental?
+
+I'm not sure if it's fundamental, but in Randy's example
+New_Gen.New_Lim is certainly by-reference according to 6.2(7),
+because it is "a nonprivate type with the reserved word limited
+in its declaration". The definition of by-copy and by-reference was
+written in such a way that the two categories were mutually exclusive.
+Not anymore if Randy's example becomes legal. So at a minimum there is a
+logical inconsistency that needs fixing.
+
+But I am seriously concerned that there might be other places in the RM
+where we assumed that elementary types were not limited. Someone will
+have to look at all the usages of "limited" to see if making Randy's example
+legal could cause trouble.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, May 25, 2008  6:58 AM
+
+But from the point of view of the generic, New_Gen.New_Lim is a *private* type.
+I don't think that changes when we instantiate, since the private part is not
+visible outside the generic. Certainly if this were in the body that is the
+position we would have to take.
+
+So I think we have to make sure that 6.2(7) doesn't make such a type into a
+by-reference type. It must remain a *private* type, even after instantiation,
+just as it would if it were in the body.
+
+We have had a rash of cases where we recheck legality rules in the private part,
+but many of those have had to do with tagged types, where the compile-time and
+run-time properties are all intertwined. With untagged types, I think we can
+generally treat the private part pretty much like the body of the generic,
+with no rechecking of legality rules, and with the "kind" of the type remaining
+what it was from the point of view of the generic, rather than of the instance.
+We'll have to be sure that the rules that matter (like 6.2(7)) are consistent
+with this approach, of course.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Monday, May 26, 2008  12:04 AM
+
+> But from the point of view of the generic,
+> New_Gen.New_Lim is a *private* type.  I don't
+> think that changes when we instantiate, since
+> the private part is not visible outside
+> the generic.  Certainly if this were in the
+> body that is the position we would have to
+> take.
+
+Hmm, that's an interesting viewpoint. I never saw it that way. I have always
+thought that "In an instance, a generic_formal_parameter_declaration
+declares a view whose properties are identical to those of the actual" (12.3(15)).
+In this interpretation the actual is an integer type, so the formal is an
+integer type too, and New_Lim is a type derived from an integer type.
+Incidentally, that's the way I have implemented it (not that it proves anything).
+
+I am curious to know what verse of the RM you think supports your viewpoint
+that New_Lim is somehow private in an instance.
+ 
+> We have had a rash of cases where we recheck legality
+> rules in the private part, but many of those have
+> had to do with tagged types, where the compile-time
+> and run-time properties are all intertwined.  With
+> untagged types, I think we can generally treat the
+> private part pretty much like the body of the generic,
+> with no rechecking of legality rules, and with
+> the "kind" of the type remaining what it was from
+> the point of view of the generic, rather than of
+> the instance.
+
+This would be a more convincing argument if there were more than one or
+two rules that *don't* get rechecked in the private part.  As Randy mentioned,
+3.4(5/2) if one of the few rules, and perhaps the only one, for which this
+is true.  I have a hard time believing that all the other rules actually pertain
+to tagged types.  It seems for instance that 4.9(37/2) pretty much contradicts
+your statement (the private part is *not* treated like the body).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, May 26, 2008  7:04 AM
+
+One of the "language design principles" Bob and I had was that generic formal
+privates and package privates were sort of "duals" of one another.
+In a package private, the full type is given after the word "private."
+In the generic formal private, the full type is the actual.
+
+I'll see if I can track down the words in the AARM that discuss this.
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Monday, May 26, 2008  7:17 AM
+
+I'm aware of the duality, and I remember reading the explanation in some
+AARM note, but that still doesn't convince me that New_Lim is a private type
+(note that 6.2(7) doesn't even say "descended from a private type").
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, May 27, 2008  6:47 PM
+
+>> Or am I missing something fundamental?
+		
+> I'm not sure if it's fundamental, but in Randy's example 
+> New_Gen.New_Lim is certainly by-reference according to 6.2(7), because 
+> it is "a nonprivate type with the reserved word limited in its 
+> declaration".  The definition of by-copy and by-reference was written 
+> in such a way that the two categories were mutually exclusive. Not anymore
+> if Randy's example becomes legal.
+> So at a minimum there is a logical inconsistency that needs fixing.
+
+I think you are correct that there is something wrong with 6.2(7), but it
+doesn't have anything to do specifically with my example. It's just that this
+wording needs to take derived limited types into account. Consider the example
+that Tucker implied earlier:
+
+    package P is
+       type LP is limited private;
+       procedure Prim (Param : in LP);
+    private
+       type LP is new Integer;
+    end P;
+
+LP surely is a by-copy type (by 6.2(3)), so Param is passed by copy. So, now
+make a non-generic package:
+
+    with P;
+    package Q is
+       type New_LP is new P.LP;
+    end Q;
+
+Now, Pascal says 6.2(7) says that New_LP is a by-reference type. So the
+inherited Prim's Param is supposed to be passed by-reference. How are we
+going to do that?? The original Prim is pass-by-copy! You can fake
+pass-by-copy for a pass-by-reference parameter, but not the reverse.
+
+Obviously something is wrong with 6.2(7), it wasn't updated to take
+explicitly limited derived types into account.
+
+> But I am seriously concerned that there might be other places in the 
+> RM where we assumed that elementary types were not limited.  Someone 
+> will have to look at all the usages of "limited" to see if making 
+> Randy's example legal could cause trouble.
+
+I think this is FUD. We've had types like LP in the example above in Ada
+since the beginning of time, and the planet hasn't stopped turning (and
+implementations haven't crashed, well at least not most of the time).
+I can buy the idea that there may be latent bugs in this area (there
+aren't many areas where I'd be surprised by latent bugs!), but I think
+we should worry about them when we find them, not sooner.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Tuesday, May 27, 2008  6:57 PM
+
+>> One of the "language design principles" Bob and I had was that 
+>> generic formal privates and package privates were sort of "duals" of 
+>> one another.
+>> In a package private, the full type is given after the word 
+>> "private."  In the generic formal private, the full type is the 
+>> actual.
+
+> I'm aware of the duality, and I remember reading the explanation in 
+> some AARM note, but that still doesn't convince me that New_Lim is a 
+> private type (note that 6.2(7) doesn't even say "descended from a private type").
+
+I suspect the situation is similar to that for "constrained partial view",
+where derivation does not eliminate any privateness.
+
+But in any case, I think this is all irrelevant: 6.2(7) is badly
+broken (limited derived types should not be included). Simple as
+that. (And thanks for finding it, Pascal, we've managed to miss the
+problem for far too long).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, May 27, 2008  10:35 PM
+
+How about if we change 6.2(7) to:
+
+    * a record type with the reserved word limited in its definition;
+
+Or:
+
+    * an explicitly limited record type;
+
+Doesn't that solve the problem?  I'm not sure what we had in mind when we
+said "nonprivate" other than "record."
+
+****************************************************************
+
+From: Pascal Leroy
+Sent: Wednesday, May 28, 2008  12:05 AM
+
+Yes I think it works.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, May 28, 2008  2:59 PM
+
+> Doesn't that solve the problem?  I'm not sure what we had in mind when 
+> we said "nonprivate"
+> other than "record."
+
+I think we (well, really you Ada 9x guys) just were trying to avoid defining
+lots of new terms, and thus you didn't name "explicitly limited record type".
+And this was a particularly bad way to describe explicitly limited record types
+in Ada 95.
+
+I just did a scan of the Ada syntax for uses of the word limited, and there
+isn't any other types of interest that are covered by this wording: otherwise
+there are various private and formal types (excluded already, or we surely want
+them excluded), limited with (obviously irrelevant), derived types (new in the
+Amendment), and explicitly limited records.
+
+P.S. I never saw anyone actually agree or disagree with my analysis of the problem.
+Besides wanting the reinforcement before I add this to the AI, the ego boost would
+be nice, too. ;-) I was particularly interested how Pascal proposed to pass New_LP
+parameters by reference to a routine that expects by-copy parameters. (Knowing the
+answer to this would help implement shared generics!) I presume that you agree with
+the existence of the problem since you're going on to solve it...
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent