CVS difference for ais/ai-00294.txt

Differences between 1.8 and version 1.9
Log of other versions for file ais/ai-00294.txt

--- ais/ai-00294.txt	2004/11/25 00:03:35	1.8
+++ ais/ai-00294.txt	2005/01/28 02:10:44	1.9
@@ -520,3 +520,275 @@
 
 ****************************************************************
 
+!topic AI-228 and generics
+!reference AI95-00228; RM95 3.9.3(6), 12.5.1(21)
+!from Adam Beneschan 05-01-03
+!discussion
+
+    package Pak1 is
+       type T1 is abstract tagged null record;
+       function F2 return T1 is abstract;
+       generic
+          type T2 is new T1 with private;
+       package Pak2 is
+          X : T2 := F2;
+       end Pak2;
+    end Pak1;
+
+    with Pak1;
+    package Pak3 is
+       type T3 is new Pak1.T1 with null record;
+       function F2 return T3;
+       package New_Pak2 is new Pak1.Pak2 (T3);
+    end Pak3;
+
+When the generic formal derived type T2 is declared, an inherited
+subprogram F2 is also implicitly declared immediately after the
+declaration of T2.  According to 3.9.3(6), this is a subprogram that
+"shall be overridden" with a nonabstract subprogram; but that since T2
+is a generic formal type, the nonabstract subprogram will "necessarily
+be provided by the actual type".
+
+The declaration of X contains an initial expression that includes a
+call to the implicitly declared F2, which is not a dispatching call.
+As I understand AI-228, though, since this implicitly declared F2 is a
+"shall be overridden" function, the restrictions on abstract function
+calls don't apply to it, and in particular the rule in 3.9.3(7)
+("nondispatching calls to an abstract subprogram are not allowed").
+
+Correct so far?
+
+OK, now we later instantiate Pak2.  Here, we've declared a nonabstract
+derived type T3 and overridden the abstract F2 for it.  According to
+12.5.1(21), the instance New_Pak2 contains a copy of the implicitly
+declared F2, and "the copy of such an implicit declaration declares a
+view of the corresponding primitive subprogram of the ancestor, even
+if this primitive has been overridden for the actual type".  As I read
+this rule, then, whenever the implicitly declared F2 is referenced in
+the instance, the meaning of this reference is a view of the abstract
+"function F2 return T1" declared in Pak1, even though the dynamic
+semantics are that the overriding subprogram ("function F2 return T3")
+would be executed.  This would make it seem that the declaration of X
+in the instance is illegal, since the initial expression contains a
+nondispatching call to F2, and F2 is a view of the primitive
+subprogram of the ancestor, which is *abstract*, and thus the rule in
+3.9.3(7) is violated.  This interpretation seems wrong, since the
+generic is accepted but cannot be legally instantiated.
+
+So what's the story?  Did I miss something?  Is there an omission in
+12.5.1(21)?  Or does AI-228 apply here to the instance and thus modify
+the meaning of the quoted sentence in 12.5.1(21)?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, January 4, 2005  8:00 AM
+
+A "view" of something can be significantly different from
+the original.  In particular, in this case, the view
+is non-abstract, as implied by 3.9.3(6).  A similar
+situation applies in the visible part when you have
+a non-abstract private extension of an abstract ancestor.
+The non-abstract implicitly declared inherited subprogram gets
+its parameter names and defaults from the corresponding
+subprogram of the ancestor type, even if it was abstract.
+In general for dispatching operations, the spec can come
+from one place, and the body from another.
+
+****************************************************************
+
+From: Adam Beneschan
+Sent: Tuesday, January 4, 2005  10:27 AM
+
+I did think of that.  It's a somewhat confusing area of the language,
+because there are some properties that are properties of views, and
+some properties that are properties of the underlying "things"
+themselves.  For example, the same type may be limited or nonlimited
+depending on which view is currently in effect.  However, the RM hints
+at the fact that limitedness is a property of a view, in 7.5(1): "A
+limited type is (a view of) a type for which the assignment operation
+is not allowed".  I looked for evidence that abstractness was a
+property of a *view* as opposed to a property of the underlying
+subprogram itself, and I couldn't find any such evidence in the RM.
+
+Sorry, I'm not convinced.  I still think 12.5.1(21) needs some
+clarification or rewording.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 19, 2005  6:11 PM
+
+> So what's the story?  Did I miss something?  Is there an omission in
+> 12.5.1(21)?  Or does AI-228 apply here to the instance and thus modify
+> the meaning of the quoted sentence in 12.5.1(21)?
+
+I don't agree with this analysis. We had this argument in AI-294 with Pascal
+Leroy and Steve Baird, and they eventually decided that this somewhat vague
+wording is the best that we can do. (Their problem was somewhat different,
+but the conclusion is the same.) But there is no abstract operation here, so
+there is no problem.
+
+For type T3, the inherited F2 is a "shall-be-overridden" subprogram. The
+inherited F2 is not abstract! It then is overridden with a new F2. That
+means that a "view of the corresponding primitive function" is the inherited
+F2. Which, as we just determined, is a "shall-be-overridden" subprogram, and
+thus does not trigger any abstract subprogram checks.
+
+Therefore, the wording in the standard is fine. Maybe an AARM note is in
+order, but I have to wonder at the value of it.
+
+Note that the AARM notes in 3.9.3 talked way too much about "abstract" in
+this case, which has proven confusing even to the ARG. I improved them to
+tone that down some (it's the "shall-be-overridden" case that is the most
+common and usually the most important). I hope that will help in the future.
+
+****************************************************************
+
+From: Adam Beneschan
+Sent: Wednesday, January 19, 2005  7:06 PM
+
+You're right that the *inherited* F2 is not abstract.  However, I'm
+trying to read 12.5.1(21) carefully.  This says that in the instance
+New_Pak2, the implicit declaration of F2 is copied, and the copy
+"declares a view of the corresponding primitive subprogram of the
+*ancestor*" (emphasis mine).  The ancestor in this case is T1, right?
+(That's the ancestor type mentioned in the generic formal derived
+type.  See 12.5.1(5).)  The "corresponding primitive subprogram of the
+ancestor", to me, is therefore the subprogram F2 that is a primitive
+subprogram of T1; that is, the F2 that was explicitly declared on the
+line before the word "generic".  This is indisputably an abstract
+function; it is *not* the implicitly inherited one, nor is it a
+shall-be-overridden one.
+
+It appears that nobody thinks this is what the intent is.  In AI-294,
+Pascal said, "It is clear from 12.5.1(21) and AARM 12.5.1(21.a) that
+in the instance the name of the primitive subprogram refers to the
+overridden one".  But the "primitive subprogram of the ancestor" that
+12.5.1(21) speaks of is, in this case, not overridden anywhere.  It
+looks to me as if, instead of saying "a view of the corresponding
+primitive subprogram of the ancestor", it should say something like "a
+view of some subprogram that was implicitly inherited from the
+primitive subprogram of the ancestor"---at least according to what
+everyone thinks this clause means.  Of course, in terms of static
+semantics, there aren't too many differences between the two
+subprograms---the parameter names and defaults would be the same---BUT
+it seems to me that some properties *are* different, including in
+particular abstractness (which is True for the primitive subprogram of
+the ancestor, and False for the implicitly inherited subprogram that
+the clause is really intended to refer to).
+
+(Please bear in mind that I have *not* argued about which subprogram
+gets dispatched to at runtime; this is an issue of static semantics
+only.)
+
+Anyway, I hope this helps clarify exactly what the source of my
+confusion is.  It still appears to me that 12.5.1(21) isn't quite
+correct.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 19, 2005  7:54 PM
+
+> You're right that the *inherited* F2 is not abstract.  However, I'm
+> trying to read 12.5.1(21) carefully.
+
+Don't do that! We agreed when we discussed AI-294 that it isn't as clear as
+one would like, but every "fix" made it much worse. We essentially decided
+to apply Dewar's rule to this paragraph: alternative interpretations are
+silly, so there is no problem know what the rule means.
+
+> This says that in the instance
+> New_Pak2, the implicit declaration of F2 is copied, and the copy
+> "declares a view of the corresponding primitive subprogram of the
+> *ancestor*" (emphasis mine).  The ancestor in this case is T1, right?
+> (That's the ancestor type mentioned in the generic formal derived
+> type.  See 12.5.1(5).)  The "corresponding primitive subprogram of the
+> ancestor", to me, is therefore the subprogram F2 that is a primitive
+> subprogram of T1; that is, the F2 that was explicitly declared on the
+> line before the word "generic".  This is indisputably an abstract
+> function; it is *not* the implicitly inherited one, nor is it a
+> shall-be-overridden one.
+
+Sure, if you read this literally. But if you do that, you also get a
+function with the profile:
+    function F2 return T1 is abstract;
+which is completely silly: it doesn't even have the right type. So you can't
+get to a problem with this approach.
+
+That's the whole argument in AI-294: what does corresponding mean here? It
+has to mean the "inherited subprogram of the actual type that corresponds to
+the primitive subprogram of the ancestor", because that is the only way to
+even get the correct types for the operation (who cares about other
+properties if the types are wrong?). Once you agree with that, then there is
+no problem. (Note that the above wording wouldn't be enough to fix the
+paragraph, because it wouldn't work for untagged types.)
+
+> Anyway, I hope this helps clarify exactly what the source of my
+> confusion is.
+
+It does. Your derivation of the meaning ends up with an operation with the
+wrong type(s), so that could not possibly be the meaning of the sentence in
+question.
+
+> It still appears to me that 12.5.1(21) isn't quite
+> correct.
+
+It's correct, just not as clear as it could be. And we previously discussed
+that and decided not to change anything, because the cure was worse than the
+disease. (Remember that this wording applies to untagged types, too, so
+things can get really messy really fast if you're not careful.) Tucker and
+Pascal spend several lunch hours trying to figure out improvements, and
+decided not to change anything. Why would we want to revisit that? There's
+no disagreement on the meaning.
+
+****************************************************************
+
+From: Nick Roberts
+Sent: Friday, January 21, 2005 12:11 PM
+
+"Randy Brukardt" <randy@rrsoftware.com> wrote:
+
+> > You're right that the *inherited* F2 is not abstract.  However, I'm
+> > trying to read 12.5.1(21) carefully.
+>
+> Don't do that! We agreed when we discussed AI-294 that it isn't as clear
+> as one would like, but every "fix" made it much worse. We essentially
+> decided to apply Dewar's rule to this paragraph: alternative
+> interpretations are silly, so there is no problem know what the rule
+> means.
+
+I'm not a huge fan of Dewar's rule. Where possible, it is better to have
+rules that are both correct and clear, rather than just rules that are
+correct (but require hours of deep analysis to fully understand). Obviously,
+I understand that coming up with rules that are both correct and clear is a
+challenge -- a monumental one, I guess -- especially for an amendment.
+
+> ...
+> > It still appears to me that 12.5.1(21) isn't quite correct.
+>
+> It's correct, just not as clear as it could be. And we previously
+> discussed that and decided not to change anything, because the cure was
+> worse than the disease. (Remember that this wording applies to untagged
+> types, too, so things can get really messy really fast if you're not
+> careful.) Tucker and Pascal spend several lunch hours trying to figure out
+> improvements, and decided not to change anything. Why would we want to
+> revisit that? There's no disagreement on the meaning.
+
+Fair enough, and maybe some good AARM notes on the subject would be most
+appropriate in this case.
+
+Remember that some of us :-) are going to be writing a compiler using these
+rules. Whilst the AARM notes are priceless in helping us do it, we are (or I
+am, anyway) aiming at an implementation that is 100.000% compliant with the
+standard, which means our decisions must ultimately be based on the standard
+itself.
+
+Frankly, some of these rules twist my brain. I would welcome any kind of
+rationalisation, clariification, or simplification you can achieve (without
+overly compromising your other goals). But I salute you (the ARG) for your
+Herculean efforts.
+
+*****************************************************************
+

Questions? Ask the ACAA Technical Agent