CVS difference for ais/ai-00200.txt

Differences between 1.1 and version 1.2
Log of other versions for file ais/ai-00200.txt

--- ais/ai-00200.txt	1998/09/30 00:17:36	1.1
+++ ais/ai-00200.txt	1999/03/20 00:13:19	1.2
@@ -1,24 +1,206 @@
-!standard 03.02.03 (07)                               98-03-27  AI95-00200/00
+!standard 03.02.03 (07)                               99-03-14  AI95-00200/01
 !class binding interpretation 98-03-27
+!status work item 99-03-14
 !status received 98-03-27
 !priority Low
 !difficulty Medium
 !subject Generic formal subprograms as dispatching operations
 
-!summary 98-03-27
+!summary 99-03-14
 
+Generic formal subprograms are never primitive operations and hence
+cannot be dispatching operations, even though they can potentially
+override an implicitly declared primitive operation of a formal type.
+The primitive operations of a formal type comprise only the predefined
+operators and implicitly declared subprograms of the formal type.
+
+!question 99-03-14
+
+The definition of primitive subprograms in 3.2.3(7) suggests that the copies
+of generic formal subprograms in an instance can be dispatching operations if
+they override any implicitly declared primitive subprograms there.  It is
+unclear how dispatching calls on such subprograms should be performed.
+
+For example:
+
+   package P is
+      type Root is tagged ...
+      -- implicit "="(left, right : Root) return boolean;
+      function Foo (l,r : Root) return boolean;
+   end P;
+   use P;
+
+   generic
+      type T is new Root with private;
+      -- implicit "="(left, right : T) return boolean;      -- (1)
+      -- implicit Foo(left, right : T) return boolean;      -- (2)
+      with function "="(l,r : T) returns boolean;           -- (3)
+      with function Foo(l,r : T) returns boolean;           -- (4)
+   package G is
+      procedure Test (X : T'class);
+   end G;
+
+   function Bar (l,r : Root) return boolean;
+
+   package I1 is new G(Root, "=", Foo);
+   package I2 is new G(Root, Foo, "=");
+   package I3 is new G(Root, Bar, Bar);
+
+In each of the instances of G, the declaration of T declares a new view of
+Root by RM95 12.3(15).  The predefined "=" operator (1) is copied and is
+considered primitive by RM95 12.5.1(21) and RM95 3.2.3(3).  Likewise, the Foo
+function (2) is copied and is considered primitive by RM95 12.5.1(21) and
+RM95 3.2.3(4).  The user-defined "=" operator (3) and Foo function (4)
+declare new views of the generic actual subprograms specified for each
+instance.  The "=" (3) and Foo (4) operations are declared in the same
+declarative region as the predefined ones (1) and (2) and override them by
+RM95 8.3(10).  So, it seems that it should be considered primitive, too, by
+RM95 3.2.3(7).
+
+Because the "=" (3) and Foo (4) operations are primitive operations of (a
+view of) a tagged type in each of the instances, they should also be
+dispatching operations by RM95 3.9.2(1).
+
+[It is not the intent that formal subprograms should ever be primitive
+operations of a type.]
+
+Note that a similar problem exists for a formal subprogram overriding the
+primitive "=" operator of a formal tagged private type:
+
+   generic
+      type T is new tagged private;
+      -- implicit "="(left, right : T) return boolean;      -- (1)
+      with function "="(l,r : T) returns boolean;           -- (3)
+   package G is
+      procedure Test (X : T'class);
+   end G;
+
+   package body G is
+      procedure Test (X : T'class) is
+      begin
+         ... := (X = X);  -- [Illegal: "=" (3) is not dispatching]
+      end Test;
+   end G;
+
+Is the formal function "=" a primitive operation of type T? [No.]
+
+Also note that a similar problem exists for ordinary subprograms overriding
+primitive operations of a generic formal tagged private or generic formal
+derived tagged type:
+
+   generic
+      type T is new Root with private;
+      -- implicit "="(left, right : T) return boolean;      -- (1)
+      -- implicit Foo(left, right : T) return boolean;      -- (2)
+   package G is
+      function "="(l,r : T) returns boolean;                -- (3)
+      function Foo(l,r : T) returns boolean;                -- (4)
+
+      procedure Test (X : T'class);
+   end G;
+
+   package body G is
+      function "="(l,r : T) returns boolean is ... end "=";
+
+      function Foo(l,r : T) returns boolean is ... end Foo;
+
+      procedure Test (X : T'class) is
+      begin
+         ... := (X = X);    -- [Illegal: "=" (3) is not dispatching]
+         ... := Foo(X, X);  -- [Illegal: Foo (4) is not dispatching]
+      end Test;
+   end G;
+
+Are the declarations of "=" and Foo in the visible part of G
+primitive operations of the formal type T? [No.]
+
+So, what subprograms should be executed for calls to the "=" (3) and Foo (4)
+operations in each of the calls to Test?
+
+[The calls are illegal because the invoked subprograms are not dispatching
+operations.]
+
+!recommendation 99-03-14
+
+The rule given in 3.2.3(7) is not intended to apply to subprograms that
+override the implicitly declared primitive subprograms of a generic
+formal type.  The only operations that are primitive subprograms
+of a formal type are the subprograms implicitly declared at the point
+of the formal type declaration.
+
+In particular, a formal subprogram that overrides a primitive operation
+of a formal type is not a primitive operation of the type, and thus
+is not a dispatching operation of the type.  Similarly, a subprogram
+declared immediately within the package specification of a generic
+formal package declaration and overrides a primitive operation of a
+formal type of the generic is not a primitive of the type, even though
+it occurs within the same declarative region as the formal type.
+
+!wording 99-03-14
+
+Revise 3.2.3(7) to make it clear that the rule does not apply to
+generic formal types, e.g.:
+
+  "{In the case of a nonformal type,} any subprograms not covered above
+  that are explicitly declared immediately within the same declarative
+  region as the type and that override (see 8.3) other implicitly
+  declared primitive subprograms of the type."
+
+!discussion 99-03-14
+
+The principal question asked by the submitter is whether formal
+subprograms can ever be dispatching operations of a formal type.
+In particular, when a formal subprogram overrides an inherited
+subprogram of a formal derived tagged type, is it defined to
+be a primitive operation of the formal type and thus can it be
+called with dynamically typed operands?  The current wording
+of 3.2.3(7) seems to imply that such a formal subprogram is
+a primitive of the formal type, because it satisfies the
+requirements of being declared immediately within the same
+declarative region as the formal type (8.1) and of overriding
+an implicitly declared primitive subprogram of the type (8.3(10)).
+
+However, it was never the intent that formal subprograms should ever
+treated as primitive operations of a formal type. In fact, the
+primitive operations for formal nonderived types are explicitly defined
+by 12.5(8) to be the predefined operators of the type, and hence could
+not include, for example, an overriding "=" function. The definition of
+the primitives for a formal derived type are not as clearly defined
+(12.5.1(21)), but it also would not make sense to include overriding
+formal subprograms in a formal derived type's set of primitives.
+
+in fact, to treat overriding formal subprograms as primitives for a
+formal tagged type would be inconsistent with the dispatching model.
+For example, if the actual subprogram associated with an overriding
+formal subprogram in an instance were not even a primitive of the
+actual type (as for one of the instantiations in the examples of the
+!question section), then it would not be sensible for this actual
+subprogram to suddenly become a dispatching primitive simply because
+it was used in an instantiation.  How would the actual subprogram be
+incorporated into the dispatch table of the actual type, and what would
+it even mean to have two subprograms associated with the same dispatch
+table entry?
+
+The submitter also raises a similar question for the situation where
+primitives of a formal type are overridden by subprograms declared in
+the specification of a formal package.  By 3.2.3(7) it would appear
+that the overriding subprograms become primitives of the formal type
+since the subprograms are declared immediately within the same
+declarative region as the formal type.  Again, it was not the intent
+that such overriding operations should become primitives of a formal
+type.
+
+Note that even though the implicitly declared primitive subprograms of
+a formal type can be overridden, this does not mean that an overriding
+operation is a primitive of the type, even though that is normally the
+case for overridings of operations of nonformal types.  In particular,
+this means that a derivation from the formal type will not inherit such
+overriding operations, but as usual will inherit the primitives of the
+formal type, even though some of them may be hidden at the point of
+derivation.
 
-!question 98-03-27
-
-
-!recommendation 98-03-27
-
-
-!wording 98-03-27
-
-
-!discussion 98-03-27
-
+The fix for this wording problem is simply to specify that the rule
+of 3.2.3(7) only applies to nonformal types.
 
 !appendix 98-03-27
 

Questions? Ask the ACAA Technical Agent