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

Differences between 1.1 and version 1.2
Log of other versions for file 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