CVS difference for ai05s/ai05-0131-1.txt
--- ai05s/ai05-0131-1.txt 2008/12/05 04:39:16 1.1
+++ ai05s/ai05-0131-1.txt 2011/02/05 06:31:34 1.2
@@ -1,4 +1,4 @@
-!standard 12.6(10) 08-12-04 AI05-0131-1/01
+!standard 12.6(10) 11-02-04 AI05-0131-1/02
!class binding interpretation 08-12-04
!status work item 08-12-04
!status received 08-10-23
@@ -9,34 +9,76 @@
!summary
-** TBD **
+The equivalence defined in AI05-0071-1 for formal subprogram matching is
+extended such that it applies to explicit as well as default actual
+subprogram. The equivalence is also explicitly given use-visibility, so
+that explicitly named, directly visible subprograms have preference over
+the implicitly created equivalent subprograms.
!question
-AI05-0071-1 allows an instantiation to automatically create a matching subprogram
-for a class-wide type if a primitive for the specific type is directly visible.
+AI05-0071-1 allows an instantiation to automatically create a matching
+subprogram for a class-wide type if a primitive for the specific type is
+directly visible.
+
+However, this requires using a use clause to get the proper visibility, which
+can clutter the visibility with many unrelated subprograms. Moreover, the
+capability is not available if the subprogram is directly specified in the
+instantiation.
-However, this requires using a use clause to get the proper visibility, which can
-clutter the visibility with many unrelated subprograms. Moreover, the capability
-is not available if the subprogram is directly specified in the instantiation.
-
It is very unusual in Ada to be able to do something by default that you cannot
do explicitly.
-Should this be corrected?
+Should this be corrected? (Yes.)
!recommendation
(See Summary.)
!wording
+
+Add after 8.4(8.2):
+
+ Certain implicit declarations may become potentially
+ use-visible in certain contexts as described in 12.6.
-** TBD **
+Add after 12.6(9):
+ If a subtype_mark in the profile of the formal_subprogram_declaration
+ denotes a formal private or formal derived type and the actual type
+ for this formal type is a class-wide type T'Class, then for the
+ purposes of resolving the corresponding actual subprogram at the
+ point of the instantiation, certain implicit declarations
+ may be available as possible resolutions as follows:
+ For each primitive subprogram of T that is directly visible at
+ the point of the instantiation, and that has at least one controlling
+ formal parameter, a corresponding implicitly declared subprogram with
+ the same defining name, and having the same profile as the primitive
+ subprogram except that T is systematically replaced by T'Class
+ in the types of its profile, is potentially use-visible.
+ The body of such a subprogram is as defined in 12.5.1 for primitive
+ subprograms of a formal type when the actual type is class-wide.
+
+AARM Implementation Note:
+ Although the above wording seems to require constructing implicit
+ versions of all of the primitive subprograms of type T, it should be
+ clear that a compiler only need to consider those that could possibly
+ resolve to the corresponding actual subprogram. For instance, if the formal
+ subprogram is a procedure with two parameters, and the actual subprogram
+ name is Bar (either given explicitly or by default), the compiler
+ need not consider primitives that are functions, that have the wrong
+ number of parameters, that have defining names other than Bar, and so on;
+ thus it does not need to construct implicit declarations for those
+ primitives.
+
+
+Undo the 12.6(10) wording changes of AI05-0071, leaving only the original (i.e.,
+pre-AI05-0071) first sentence:
+
+ If a generic unit has a subprogram_default specified by a box, and the
+ corresponding actual parameter is omitted, then it is equivalent to an
+ explicit actual parameter that is a usage name identical to the
+ defining name of the formal.
-[I didn't try to figure out wording for this one. It would seem to be necessary
-to take the wording added to 12.6(10) by AI05-0071-1 and move it up to a separate
-paragraph preceding 12.6(10) so it would apply to all (non-abstract) formal
-subprograms - Editor]
!discussion
@@ -83,6 +125,116 @@
(it even goes so far as to provide selection notation for operators!), but
that is not the case here. That seems to be a mistake.
+----
+
+AI05-0071-1 also introduced another problem (noticed while rewording to fix
+the problem in the question). Since it doesn't explain where the implicit
+subprogram is declared, it is not clear how it interacts with explicit
+routines.
+
+For instance, consider the following case where the instance would have been
+legal without AI05-0071:
+
+ package Pkg1 is
+ type T1 is tagged null record;
+ procedure Foo (X1 ; T1);
+
+ generic
+ type T2 (<>) is private;
+ with procedure Foo (X2 : T2) is <>;
+ package G is
+ end G;
+ end Pkg;
+
+ with Pkg1;
+ package Pkg2 is
+ use Pkg1;
+ procedure Foo (X : T1'Class);
+ package I is new G (T1'Class); -- Ambiguous, and thus illegal?
+ end Pkg2;
+
+It is hard to figure out how the visibility rules apply to the above example
+because the AI05-0071 wording just says that a "Foo" with the right profile "is
+directly visible" without defining the declaration point (and thus, the scope)
+of this "Foo".
+
+In any case, it seems unfriendly to reject the above instantiation.
+It seems clear what the user wants.
+
+One could imagine an approach using (in effect) a preference rule, where the
+implicit declaration is only referenced if it is needed. This would introduce
+Beaujolais effects because adding/deleting a use clause could affect the need
+for the implicit declaration.
+
+Consider the variation of the above example where we replace
+ procedure Foo (X : T1'Class);
+with
+ package Foo_Pkg is
+ procedure Foo (X : T1'Class);
+ end Foo_Pkg;
+ use Foo_Pkg;
+
+and then consider the effect of deleting the "use Foo_Pkg;".
+This illustrates how a preference rule could introduce Beaujolais effects.
+
+To deal with this aspect of the problem, the proposed wording says
+that the implicit declaration is not "directly visible", but rather
+"potentially use-visible".
+
+This is the only part of the wording changes that is motivated by this
+"homograph collision" problem. The rest of the wording changes are motivated by
+the problem that this AI was originally created to address.
+
+It seems odd to introduce the possibility of a "potentially use-visible"
+declaration in a program which does not contain the reserved word "use"
+anywhere, but this seems to solve the problem and no better approach has been
+found.
+
+----
+
+The original example which motivated AI05-0071 remains legal, but now this is
+handled via the equivalence stated in the one sentence of 12.6(10) that has
+remained constant throughout all of these changes (listed above), as opposed to
+via an only-for-defaulted-parameters rule.
+
+Note that this proposal follows AI05-0071 in building implicit declarations only
+for primitive subprograms which have at least one controlling formal parameter
+(as opposed to only a controlling result), AI05-0071 got this part right -
+building on 12.5.1(23.3/2)'s weirdness seems like a bad idea. With at least one
+controlling operand, we have a nice clean wrapper model. When we only have a
+controlling result, things get messy.
+
+Note that with the proposed changes, the
+ package Foo_Pkg is
+ procedure Foo (X : T1'Class);
+ end Foo_Pkg;
+ use Foo_Pkg;
+version of the example described above will be rejected (which is a good thing -
+we don't want Beaujolais effects).
+
+It would also be rejected (for the same reason) if the actual parameter were
+specified explicitly via a simple name, as in
+
+ package Foo_Pkg is
+ procedure Foo (X : T1'Class);
+ end Foo_Pkg;
+ use Foo_Pkg;
+ package I is new G (T1'Class, Foo);
+
+but would be accepted if the name of the actual were qualified, as in
+
+ package Foo_Pkg is
+ procedure Foo (X : T1'Class);
+ end Foo_Pkg;
+ use Foo_Pkg;
+ package I is new G (T1'Class, Foo_Pkg.Foo);
+
+(and note that adding/deleting the "use Foo_Pkg;" in this version of the example
+would make no difference - that use clause has no effect on this example even if
+it is present). This shows that there is a straighforward workaround to any
+ambiguities created.
+
+
--!corrigendum 12.6(10/2)
@@ -102,7 +254,7 @@
class-wide type, and will allow the actuals for generic formal subprograms
to be dispatching subprograms "created" by the compiler, in a sense. However,
the language of AI05-0071 allows for this only if the operation is a primitive
-subprogram that is directly visible.
+subprogram that is directly visible.
I'm wondering whether this should be expanded a bit to allow renames.
Consider this example, which doesn't involve instantiation with class-wide
@@ -139,7 +291,7 @@
package Inst is new Pack2.Gen_Pack (Pack1.Root);
end Pack3;
-This option doesn't appear to be available in the class-wide type case:
+This option doesn't appear to be available in the class-wide type case:
package Pack3 is
procedure Oper_1 (X : in out Pack1.Root) renames Pack1.Oper_1;
@@ -170,8 +322,8 @@
From: Adam Beneschan
Date: Thursday, October 23, 2008 12:34 PM
-> This won't compile, because for the generic formal subprogram default
-> to be used, Oper_1 would have to be visible. This can be accomplished
+> This won't compile, because for the generic formal subprogram default
+> to be used, Oper_1 would have to be visible. This can be accomplished
> with USE or USE TYPE.
Ummm, my bad. USE TYPE wouldn't work in the above case, but it would work
@@ -253,3 +405,295 @@
explicit parameter work might not be too horrendous.
****************************************************************
+
+From: Steve Baird
+Date: Friday, February 4, 2011 1:34 PM
+
+> Summary of action items:
+> Steve:
+> AI05-0131-1 – Work with Randy and Gary to create a complete
+> proposal for this AI.
+
+Here is a proposal for this AI.
+Thanks to Randy and Gary for their review of an earlier version and suggested
+improvements.
+
+As always, feedback would be appreciated.
+
+ -- Steve
+
+--------------
+
+AI05-0071 introduced two distinct problems.
+
+There is the problem that originally motivated the current AI, the inconsistency
+between the treatment of defaulted and non-defaulted actual subrogram parameters
+for an instance.
+
+There is also the problem of determining what AI05-0071 means (and fixing it if
+we don't like the answer) in the case where the instance would have been legal
+without AI05-0071, as in
+
+ package Pkg1 is
+ type T1 is tagged null record;
+ procedure Foo (X1 ; T1);
+
+ generic
+ type T2 (<>) is private;
+ with procedure Foo (X2 : T2) is <>;
+ package G is
+ end G;
+ end Pkg;
+
+ with Pkg1;
+ package Pkg2 is
+ use Pkg1;
+ procedure Foo (X : T1'Class);
+ package I is new G (T1'Class); -- ambiguous, and thus illegal?
+ end Pkg2;
+
+Recall that AI05-0071 introduces the following mouthful:
+ If a subtype_mark in the profile of the formal_subprogram_declaration
+ denotes a formal private or formal derived type and the actual type
+ for this formal type is a class-wide type T'Class, then for the
+ purposes of resolving this default_name at the point of the
+ instantiation, for each primitive subprogram of T that has a matching
+ defining name, that is directly visible at the point of the
+ instantiation, and that has at least one controlling formal parameter,
+ a corresponding subprogram with the same defining name is directly
+ visible, but with T systematically replaced by T'Class in the types of
+ its profile. The body of such a subprogram is as defined in 12.5.1 for
+ primitive subprograms of a formal type when the actual type is
+ class-wide.
+
+It is hard to figure out how the visibility rules apply to the above example
+because the AI05-0071 wording just says that a "Foo" with the right profile "is
+directly visible" without defining the declaration point (and thus, the scope)
+of this "Foo".
+
+In any case, it seems unfriendly to reject the above instantiation.
+It seems clear what the user wants.
+
+One could imagine an approach using (in effect) a preference rule, where the
+implicit declaration is only referenced if it is needed. This would introduce
+Beaujolais effects because adding/deleting a use clause could affect the need
+for the implicit declaration.
+
+Consider the variation of the above example where we replace
+ procedure Foo (X : T1'Class);
+with
+ package Foo_Pkg is
+ procedure Foo (X : T1'Class);
+ end Foo_Pkg;
+ use Foo_Pkg;
+
+and then consider the effect of deleting the "use Foo_Pkg;".
+This illustrates how a preference rule could introduce Beaujolais effects.
+
+To deal with this aspect of the problem, the proposed wording given below says
+that the implicitly declared declaration is not "directly visible", but rather
+"potentially use-visible".
+
+This is the only part of the wording changes that is motivated by this
+"homograph collision" problem. The rest of the wording changes are motivated by
+the problem that this AI was originally created to address.
+
+It seems odd to introduce the possibility of a "potentially use-visible"
+declaration in a program which does not contain the reserved word "use"
+anywhere, but this seems to solve the problem and no better approach has been
+found.
+
+The proposed wording for this AI:
+
+====
+
+!wording
+
+Add after 8.4(8.2)
+ Certain implicitly declared declarations may become potentially
+ use-visible in certain contexts as described in 12.6.
+
+Add after 12.6(9):
+ If a subtype_mark in the profile of the formal_subprogram_declaration
+ denotes a formal private or formal derived type and the actual type
+ for this formal type is a class-wide type T'Class, then for the
+ purposes of resolving the corresponding actual subprogram at the
+ point of the instantiation, certain implicitly declared declarations
+ may be available as possible resolutions as follows:
+ For each primitive subprogram of T that has a matching defining
+ name, that is directly visible at the point of the instantiation,
+ and that has at least one controlling formal parameter, a
+ corresponding implicitly declared subprogram with the same
+ defining name, and having the same profile as the primitive
+ subprogram except that T is systematically replaced by T'Class
+ in the types of its profile, is potentially use-visible.
+ The body of such a subprogram is as defined in 12.5.1 for primitive
+ subprograms of a formal type when the actual type is class-wide.
+
+Undo the 12.6(10) wording changes of AI05-0071, leaving only the original (i.e.,
+pre-AI05-0071) first sentence:
+
+ If a generic unit has a subprogram_default specified by a box, and the
+ corresponding actual parameter is omitted, then it is equivalent to an
+ explicit actual parameter that is a usage name identical to the
+ defining name of the formal.
+
+====
+
+The original example which motivated AI05-0071 remains legal, but now this is
+handled via the equivalence stated in the one sentence of 12.6(10) that has
+remained constant throughout all of these changes (listed above), as opposed to
+via an only-for-defaulted-parameters rule.
+
+Note that this proposal follows AI05-0071 in building implicit declarations only
+for primitive subprograms which have at least one controlling formal parameter
+(as opposed to only a controlling result), AI05-0071 got this part right -
+building on 12.5.1(23.3/2)'s weirdness seems like a bad idea. With at least one
+controlling operand, we have a nice clean wrapper model. When we only have a
+controlling result, things get messy.
+
+Note that with the proposed changes, the
+ package Foo_Pkg is
+ procedure Foo (X : T1'Class);
+ end Foo_Pkg;
+ use Foo_Pkg;
+version of the example described above will be rejected (which is a good thing -
+we don't want Beaujolais effects).
+
+It would also be rejected (for the same reason) if the actual parameter were
+specified explicitly via a simple name, as in
+
+ package Foo_Pkg is
+ procedure Foo (X : T1'Class);
+ end Foo_Pkg;
+ use Foo_Pkg;
+ package I is new G (T1'Class, Foo);
+
+but would be accepted if the name of the actual were qualified, as in
+
+ package Foo_Pkg is
+ procedure Foo (X : T1'Class);
+ end Foo_Pkg;
+ use Foo_Pkg;
+ package I is new G (T1'Class, Foo_Pkg.Foo);
+
+(and note that adding/deleting the "use Foo_Pkg;" in this version of the example
+would make no difference - that use clause has no effect on this example even if
+it is present).
+
+****************************************************************
+
+From: Bob Duff
+Date: Friday, February 4, 2011 2:17 PM
+
+> As always, feedback would be appreciated.
+
+Looks good to me.
+
+> given below says that the implicitly declared declaration is
+
+"implicitly declared declaration" --> "implicit declaration"
+throughout. Declarations aren't declared, unless you're the DOR Dept. ;-)
+
+****************************************************************
+
+From: Steve Baird
+Date: Friday, February 4, 2011 2:33 PM
+
+> "implicitly declared declaration" --> "implicit declaration"
+> throughout. Declarations aren't declared, unless you're the DOR Dept.
+> ;-)
+>
+
+Sounds right.
+
+You probably don't get your cash from an ATM machine either.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Friday, February 4, 2011 11:39 PM
+
+...
+> You probably don't get your cash from an ATM machine either.
+
+Gee, I do. :-) I also use the ACATS test suite all of the time. (Indeed, I
+usually refer to it that way on comp.lang.ada so the reference is clear to
+newbies, even though that's technically redundant.)
+
+BTW, it took me a long time (until just now, even though I first read this
+message when it was sent 10 hours ago) to even figure out what you were getting
+at.
+
+In any case, I've turned your original message into a proper AI (with the
+change), so this item can be crossed off from the open action item list.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Saturday, February 5, 2011 12:04 AM
+
+Wording issue:
+
+...
+> Add after 12.6(9):
+> If a subtype_mark in the profile of the formal_subprogram_declaration
+> denotes a formal private or formal derived type and the actual type
+> for this formal type is a class-wide type T'Class, then for the
+> purposes of resolving the corresponding actual subprogram at the
+> point of the instantiation, certain implicit declarations
+> may be available as possible resolutions as follows:
+> For each primitive subprogram of T that has a matching defining
+> name, that is directly visible at the point of the instantiation,
+> and that has at least one controlling formal parameter, a
+> corresponding implicitly declared subprogram with the same
+> defining name, and having the same profile as the primitive
+> subprogram except that T is systematically replaced by T'Class
+> in the types of its profile, is potentially use-visible.
+> The body of such a subprogram is as defined in 12.5.1 for primitive
+> subprograms of a formal type when the actual type is class-wide.
+
+The indented wording starts "For each primitive subprogram of T that has a
+matching defining name, ..."
+
+"matching defining name" to what?? The wording never says, at least not clearly.
+
+In AI05-0071-1, it was matching the name of the formal subprogram, but that
+isn't right here -- if the name is given explicitly, we want routines that match
+that name, not anything else.
+
+I'm not sure it is worth trying to restrict the routines that get created here.
+Use visibility seems to eliminate most problems that could occur, and the
+limitation to use for "resolving the corresponding actual subprogram" seems to
+eliminate the rest. So I would just drop "matching defining name". If we do want
+to restrict them, we need a lot more complex wording than "matching defining
+name"!
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Saturday, February 5, 2011 12:28 AM
+
+Having thought about this some more, it seems wrong to mention the defining name in
+any case. There are lots of properties which would prevent a candidate subprogram from
+matching a formal subprogram: wrong "kind" (procedure vs. function), wrong name,
+wrong number of parameters, wrong type for some parameter or the result, etc. Any
+property of a type conformant profile can be used in resolution, along with the
+defining name (that's what "expected profile" means). So why hone in on that one
+property: they're all equally relevant.
+
+So I dropped the "matching defining name" wording, and added the following AARM note:
+
+AARM Implementation Note:
+ Although the above wording seems to require constructing implicit
+ versions of all of the primitive subprograms of type T, it should be
+ clear that a compiler only need to consider those that could possibly
+ resolve to the corresponding actual subprogram. For instance, if the formal
+ subprogram is a procedure with two parameters, and the actual subprogram
+ name is Bar (either given explicitly or by default), the compiler
+ need not consider primitives that are functions, that have the wrong
+ number of parameters, that have defining names other than Bar, and so on;
+ thus it does not need to construct implicit declarations for those
+ primitives.
+
+****************************************************************
\ No newline at end of file
Questions? Ask the ACAA Technical Agent