CVS difference for ais/ai-00251.txt

Differences between 1.16 and version 1.17
Log of other versions for file ais/ai-00251.txt

--- ais/ai-00251.txt	2003/09/30 02:01:11	1.16
+++ ais/ai-00251.txt	2003/10/29 22:54:10	1.17
@@ -1,4 +1,4 @@
-!standard 03.04    (02)                            03-09-02  AI95-00251/08
+!standard 03.04    (02)                            03-10-15  AI95-00251/09
 !standard 03.09.01 (02)
 !class amendment 00-12-04
 !status work item 00-12-04
@@ -44,18 +44,40 @@
 
 !proposal
 
-An interface type is a new kind of componentless abstract tagged type.
+An interface type is a new kind of componentless abstract tagged type,
+e.g.
 
+    package Pkg1 is
+      type T1 is Interface;
+      procedure P (X : T1) is abstract;
+    end Pkg1;
+
 In addition to normal linear (i.e. single parent) derivation, a tagged type
 may now be derived from zero or more interface types, thereby inheriting
-their primitive subprograms.
+their primitive subprograms, e.g.
+
+    with Pkg1;
+    with Some_Package;
+    package Pkg2 is
+      type T2 is new Some_Package.Some_Tagged_Type and Pkg1.T1 with null record;
+      procedure P (X : T2);
+    end Pkg2;
 
 The primitive subprograms of an interface type must either be abstract
 or "null" (See AI-348 for the definition of null procedures).
 
 The class-wide type corresponding to an interface type covers all of the
-types derived from that interface type. This allows conversion between
-the classwide type and any type which is derived from the interface type.
+types derived from that interface type:
+
+    with Pkg1, Pkg2;
+    package Pkg3 is
+      type T1_Ref is access all Pkg1.T1'Class;
+      T2_Var : aliased Pkg2.T2;
+      Ref : T1_Ref := T2_Var'Access;
+    end Pkg3;
+
+This also allows conversion between the classwide type and any type which is
+derived from the interface type.
 
 In previous discussions (and in the discussion of the problem, above),
 there have been references to a specific type "implementing" an interface
@@ -72,6 +94,264 @@
 
 See the Wording section for details.
 
+!wording
+
+3.2.1 Type Declarations
+
+Add to syntax
+
+        type_definition ::= ... | interface_type_definition
+
+
+
+3.4 Derived Types and Classes
+
+Replace syntax section with
+
+        interface_list ::= interface_subtype_mark {AND interface_subtype_mark}
+
+        derived_type_definition ::=
+            [ABSTRACT] NEW parent_subtype_indication
+            [[AND interface_list] record_extension_part]
+
+
+Add at the end of paragraph 3:
+
+    A derived type has one parent type and zero or more interface ancestor types.
+
+Replace paragraph 8 with:
+
+    Each class of types that includes the parent type or an interface ancestor
+    type also includes the derived type.
+
+Add after paragraph 25:
+
+    If a type declaration names an interface type in an interface list, then
+    the declared type inherits any user-defined primitive subprograms of the
+    interface type in the same way.
+
+Add after paragraph 35 (in the Notes section):
+
+    18 An interface type which has an interface ancestor "is derived from"
+    that type, but it is not "a derived type". Conversely, a derived
+    type is never an interface type.
+
+3.4.1 Derivation Classes
+
+Insert after the first sentence of paragraph 2:
+
+     A derived type or interface type is also derived from each of its
+     interface ancestor types, if any.
+
+Replace the last sentence of paragraph 10 with:
+
+    The ultimate ancestor of a type is the ancestor of that type, if any, that
+    is not a descendant of any other type and that is not an interface
+    type (see 3.9.4).
+
+
+3.9.3 Abstract Types and Subprograms
+
+    Replace paragraphs 4-5 with
+
+        If a type inherits a subprogram corresponding to an abstract
+        subprogram or to a function with a controlling result, then
+
+           - If the inheriting type is abstract or untagged, the inherited
+             subprogram is abstract.
+
+
+3.9.4 Interface Types
+
+    This section is entirely new.
+
+        An interface type is an abstract tagged type intended for use
+        in providing a restricted form of multiple inheritance.
+        A tagged type may be derived from multiple interface types.
+
+                                 Syntax
+
+        interface_type_definition ::= [LIMITED] INTERFACE [interface_list]
+
+                                 Legality Rules
+
+        An interface type (also called an "interface") is a specific abstract
+        tagged type that is defined by an interface_type_definition.
+
+        An interface type shall have no components.
+
+        All user-defined primitive subprograms of an interface type shall be
+        abstract subprograms or null procedures.
+
+        The type of a subtype named in an interface_list shall be an
+        interface type.
+
+        If a type declaration names an interface type in an interface list,
+        then the accessibility level of the declared type shall not be
+        statically deeper than that of the interface type; also, the declared
+        type shall not be declared in a generic body if the interface type is
+        declared outside that body.
+
+        A descendant of an interface type shall be limited if and only
+        if the interface type is limited.
+
+        A full view shall be a descendant of an interface type if and only if
+        the  corresponding partial view (if any) is also a descendant of the
+        interface type.
+
+        For an interface type declared in a visible part, a primitive
+        subprogram shall not be declared in the private part.
+
+        In addition to the places where Legality Rules normally apply
+        (see 12.3), these rules apply also in the private part of an instance
+        of a generic unit.
+
+4.5.2  Relational Operators and Membership Tests
+
+    Replace paragraph 3 with
+
+        The tested type of a membership test is the type of the range or the
+        type determined by the subtype_mark. If the tested type is tagged,
+        then the simple_expression shall resolve to be of a type that is
+        convertible (see 4.6) to the tested type; if untagged, the expected
+        type for the simple_expression is the tested type.
+
+4.6 Type Conversions
+
+    Replace paragraphs 21-23 with
+
+        If the target type is tagged then either:
+
+            - The operand type shall be covered by or descended from the target
+              type; or
+
+            - The operand type shall be a class-wide type that covers the
+              target type; or
+
+            - The operand and target types shall both be class-wide types and
+              the specific type associated with at least one of them shall
+              be an interface type.
+
+        If the target type is not included in any of the above five cases,
+        there shall be a type that is an ancestor of both the target type
+        and the operand type.
+
+6.1  Subprogram Declarations
+
+Replace
+   subprogram_specification ::= PROCEDURE defining_program_unit_name
+                                          parameter_profile
+with
+   procedure_specification ::= PROCEDURE defining_program_unit_name
+                                         parameter_profile
+   subprogram_specification ::= procedure_specification
+
+
+7.3 Private Types and Private Extensions
+
+    Replace
+        private_extension_declaration ::=
+          TYPE defining_identifier [discriminant_part] IS
+          [ABSTRACT] NEW ancestor_subtype_indication WITH PRIVATE;
+    with
+        private_extension_declaration ::=
+          TYPE defining_identifier [discriminant_part] IS
+          [ABSTRACT] NEW ancestor_subtype_indication
+          [AND interface_list] WITH PRIVATE;
+
+
+8.3 Visibility
+
+Replace paragraphs 9/1 - 13 with
+
+    Two homographs are not generally allowed immediately within the same
+    declarative region unless one overrides the other (see Legality Rules
+    below). The only declarations that are overridable are the implicit
+    declarations for predefined operators and inherited primitive subprograms.
+    A declaration overrides another homograph that occurs immediately within
+    the same declarative region in the following cases:
+
+      * A declaration that is not overridable overrides one that is
+        overridable, regardless of which declaration occurs first;
+
+      * The implicit declaration of an inherited operator overrides that
+        of a predefined operator;
+
+      * An implicit declaration of an inherited subprogram overrides a
+        previous implicit declaration of an inherited subprogram.
+
+      * If two or more homographs are implicitly declared at the same place:
+
+        - At most one shall be a non-null non-abstract subprogram, and it
+          overrides all the others;
+
+        - If all are null procedures or abstract subprograms, then any null
+          procedure overrides all abstract subprograms; if more than one
+          homograph remains that is not thus overridden, then their profiles
+          shall be fully conformant with one another, and one is chosen
+          arbitrarily to override the others.
+
+      * For an implicit declaration of a primitive subprogram in a generic unit,
+        there is a copy of this declaration in an instance. However, a whole new
+        set of primitive subprograms is implicitly declared for each type
+        declared within the visible part of the instance. These new declarations
+        occur immediately after the type declaration, and override the copied
+        ones. The copied ones can be called only from within the instance; the
+        new ones can be called only from outside the instance, although for
+        tagged types, the body of a new one can be executed by a call to an
+        old one.
+
+12.5 Formal Types
+
+    Add to syntax
+
+        formal_type_declaration ::= ... | formal_interface_type_definition
+
+
+
+12.5.1 Formal Private Types
+
+    Replace
+        formal_derived_type_definition ::= [ABSTRACT] NEW subtype_mark
+                                           [WITH PRIVATE]
+    with
+        formal_derived_type_definition ::= [ABSTRACT] NEW subtype_mark
+                                           [[AND interface_list] WITH PRIVATE]
+
+
+    Add after paragraph 15:
+
+        The actual type shall be a descendant of every ancestor of
+        the formal type.
+
+
+12.5.5 Formal Interface Types
+
+    This section is entirely new.
+
+        The class determined for a formal interface type is the class of all
+        interface types.
+
+                                 Syntax
+
+        formal_interface_type_definition ::= interface_type_definition
+
+
+                                 Legality Rules
+
+        The actual type shall be a descendant of every ancestor of
+        the formal type.
+
+        The actual type shall be limited if and only if the formal type is
+        limited.
+
+13.14 Freezing Rules
+
+    Add after paragraph 7:
+
+        The declaration of a specific descendant of an interface type freezes
+        the interface type.
+
 !discussion
 
 All primitives of an interface are required to be abstract or null to minimize
@@ -140,7 +420,7 @@
 an interface. The slot-to-slot mapping remains valid and can be
 reused for the derived type, whereas a new alternative "view"
 of the dispatch table of the derived type would need to be
-constructed. A value of type Some_InterFace_Type'Class can then
+constructed. A value of type Some_Interface_Type'Class can then
 be represented at runtime as a record address paired (perhaps only
 conceptually - see next paragraph) with a reference to this dispatch
 table permutation map.
@@ -154,7 +434,7 @@
 (which is implemented by the specific type) and returns a
 reference to the associated dispatch table permutation map (aka the
 "slot-to-slot" map). Given this mapping, a "thin pointer" representation
-becomes feasible. In other words, a value of type Some_InterFace_Type'Class
+becomes feasible. In other words, a value of type Some_Interface_Type'Class
 could be represented as an unaugmented record record address.
 
 Alternatively, a "fat pointer" implementation model is possible.
@@ -180,11 +460,13 @@
 of a specific type and the tag of an interface type which it implements
 to the corresponding interface implementation descriptor.
 
-Contrary to earlier discussions, an interface-to-interface view conversion
-requires no special support. The tag of the source object is that of a
-spcific type and so what is really being implemented is a
-specific-to-interface view conversion, the only added wrinkle being that the
-specific type is not known statically.
+The Some_Interface_Type'Class'Input example described above also illustrates
+some of the difficulties that an implementation might run into if two types
+which both implement a given interface store their tag components at different
+locations. In order to perform the dispatching call, the tag of the controlling
+operand must be located. It is expected that most implementations will solve
+this problem by requiring that every tag component must reside at the same
+offset (typically zero) for all tagged types.
 
 ----
 
@@ -193,34 +475,27 @@
 1) Inherited homographs must be overridden. If the homographs are
    not mode-conformant, then this may be impossible. Life's hard.
 
-2) Nothing here (in particular, nothing in the 8.3 stuff) is intended to
+2) Nothing here (in particular, nothing in the 8.3 stuff) was *intended* to
    change the semantics of a program which declares no interface types.
-
-3) An example to illustrate some of the 8.3 stuff:
 
-           package P1 is
-               type T1 is interface;
-               procedure P (X : T1) is abstract; -- P'1
-           end P1;
-
-           package P2 is
-               type T2 is interface with P1.T1;  -- P'2 (implicit)
-               procedure P (X : T2) is abstract; -- P'3
-           end P2;
+   Consider, however:
+        generic
+          type T1 is private;
+          type T2 is private;
+        package G is
+            type T is null record;
+            procedure P (X : T; Y : T1);
+            procedure P (X : T; Y : T2);
+        end G;
 
-           type D is new Some_Tagged_Type and P1.T1 and P2.T2 with null record;
+        package I is new G (Integer, Integer); -- exports homographs
 
-       D inherits procedures P'4, P'5, and P'6, corresponding to
-       P'1, P'2, and P'3, respectively.
+        type D is new I.T; -- formerly legal, now illegal.
 
-       Since P'3 overides P'2, P'6 overrides P'5 by the "overriding is
-       preserved by inheritance" rule.
+   Disallowing this case does not seem like a bad thing, but it is a change.
 
-       Since P'2 corresponds to P'1,  P'5 overrides P'4 by the "inherited
-       copies of your parent's ops hide inherited copies of your grandparent's
-       ops" rule.
 
-4) Yes, it really is illegal if the parent type of a private extension's
+3) Yes, it really is illegal if the parent type of a private extension's
    completion happens to be descended from some interface that the
    private view was not descended from. This may turn out to be a pain.
 
@@ -263,460 +538,211 @@
    an interface that the partial view is not descended from), then
    we would have two dispatching calls to Pkg.Foo with the
    two controlling operands having the same tag and yet different
-   bodies would be executed. The two conversions to Pkg.Ifc'Class
-   would map Pkg.Foo to different slots in the same dispatch table
-   because the source types of the conversions are different.
-
-   We want to prevent this sort of thing.
-
-5) A type derived from an interface type should inherit the same subprograms
-   as a type which is derived from both the interface type and an ancestor of
-   the interface type. The two type definitions should be indistinguishable,
-   in the sense that adding or deleting the explicit redundant derivation
-   relationship should be a semantics-preserving transformation.
-
-6) It is intended that there should be no real difference between the two
-   forms of derivation from interface types. For example, replacing
-   the declaration
-       type T is new Interface_Type_1 and Interface_Type_2 with null record;
-   with
-       type T is new Interface_Type_2 and Interface_Type_1 with null record;
-   should be semantics-preserving.
-
-7) Someone asked why an interface type declared in a visible part is not
-   allowed to have primitive operations declared in the private part.
-   A dispatching call to a primitive of an interface type will execute
-   the body of a corresponding routine associated with the specific type
-   of the controlling operand. Without this restriction, it is possible that
-   the specific type might provide no such routine. It would be ok to follow
-   the example of 3.9.3(10) and allow this in the case where the subprogram
-   declared in the private part "is overriding an abstract subprogram
-   implicitly declared in the visible part", but this doesn't seem to be
-   worth the bother because this could only be used to override an abstract
-   procedure with a null procedure. There does not appear to be universal
-   agreement on this point.
-
-8) Someone asked why a limited interface cannot be implemented by a
-   non-limited type. An implementation would no longer know statically
-   whether a dispatching function call is a call to a function with a
-   return-by-reference result. This could be implemented, but it seems
-   like an unnecessary complication. The language has, as a matter of
-   general principle, steered away from constructs which would allow a
-   limited view of an object of a non-limited tagged type.
-
-9) It is intended that in the case where the implementation
-   arbitrarily chooses one overrider from among a group of inherited
-   subprograms, users should be unable to determine which
-   member was chosen. The "arbitrarily choose an overrider"
-   monkey business is needed in order to allow
-
-      package Outer is
-        package P1 is
-           type Ifc1 is interface;
-           procedure Null_Procedure (X : Ifc1) is null;
-           procedure Abstract_Subp  (X : Ifc1) is abstract;
-         end P1;
-
-         package P2  is
-           type Ifc2  is interface;
-           procedure Null_Procedure (X : Ifc2) is null;
-           procedure Abstract_Subp  (X : Ifc2) is abstract;
-         end P2;
-
-         type T is new P1.Ifc1 and P2.Ifc2;
-      end Outer;
-
-    without requiring that T explicitly override any of its inherited
-    operations. If requiring explicit overrides in this case is considered
-    to be ok, then that bit of oddness could be deleted from 8.3.
-
-    If it turns out that users can somehow determine which
-    member was chosen and that this approach introduces serious portability
-    problems, then one could impose an arbitrary-but-determininistic
-    tie-breaking scheme (e.g. make use of the order of the interface types,
-    prefering operators inherited from "earlier" types; in the above
-    example, this would mean that the operators inherited from P1.Ifc1
-    would override those inherited from P2.Ifc2).
-
-!example
-
-An example involving interface types:
-
-   type T is tagged null record;
-   T_Var : T;
-
-   package P1 is
-      type Ifc1 is interface;
-      procedure Op    (X : Ifc1) is abstract;
-      procedure Op1_A (X : Ifc1) is abstract;
-      procedure Op1_B (X : Ifc1) is abstract;
-
-      type Ref is access all Ifc1'Class;
-      Procedure Foo (X : Ref);
-   end;
-
-   package P2 is
-      type Ifc2 is interface;
-      procedure Op    (X : Ifc2) is abstract;
-      procedure Op2_A (X : Ifc2) is abstract;
-      procedure Op2_B (X : Ifc2) is abstract;
-
-      type Ref is access all Ifc2'Class;
-      Procedure Foo (X : Ref);
-   end;
-
-   package body P1 is
-      ...
-
-      procedure Foo (X : Ref) is
-         type Stream_Ptr is access all Ada.Streams.Root_Stream_Type'Class;
-         The_Stream : constant Stream_Ptr := ...;
-      begin
-          Op1_A (X.all);
-          Op1_B (X.all);
-          Ifc1'Class'Output (The_Stream, X.all);
-
-          if X.all in T'Class then
-              T_Var := T (X.all);
-          end if;
-      end Foo;
-   end P1;
-
-   package body P2 is
-      ...
-   end P2;
-
-   type D is tagged
-       with P1.Ifc1 and P2.Ifc2 and
-       record
-           F1, F2 : Integer;
-       end record;
-
-   procedure Op1_A (X : D);
-   procedure Op1_B (X : D);
-   procedure Op    (X : D);
-   procedure Op2_A (X : D);
-   procedure Op2_B (X : D);
-
-   ...
-
-   X : aliased D;
- begin
-   P1.Foo (X'Access);
-   P2.Foo (X'Access);
-   P1.Op (P1.Ifc1'Class (X));
-   P2.Op (P2.Ifc2'Class (X));
- end;
-
- --------
-
- A somewhat less artificial example:
-
-     package Object_Monitoring is
-       type Monitored_Object is interface;
-       procedure Display (Object : Monitored_Object) is abstract;
-
-       type Object_Reference is access all Monitored_Object'Class;
-       for Object_Reference'Storage_Size use 0;
-
-       procedure Register   (Object : Object_Reference);
-       procedure Unregister (Object : Object_Reference);
-       procedure Display_Registered_Objects;
-     end;
-
-     package body Object_Monitoring is
-       package Object_Reference_Sets is new ... ;
-
-       Registered_Objects : Object_Reference_Sets.Set;
-
-       procedure Display_One (Object : Object_Reference) is
-       begin
-         Display (Object.all);
-       end;
-
-       procedure Display_Registered_Objects is
-       begin
-          Object_Reference_Sets.Visit_All
-            (The_Set   => Registered_Objects,
-             Visit_One => Display_One'Access);
-       end;
-
-       ...
-     end Object_Monitoring;
-
-     package Pkg1 is
-        ...
-     end Pkg1;
-
-     with Object_Monitoring;
-     package body Pkg1 is
-         type T is tagged record F1, F2 : Integer; end record;
-
-         type Monitored_T is new T and Object_Monitoring.Monitored_Object
-             with ...;
-
-         procedure Display (Object : Monitored_T) is begin ... end;
-
-         X : aliased Monitored_T;
-
-         ...
-      begin
-         Object_Monitoring.Register (X'access);
-      end;
-
-!wording
-
-3.2.1 Type Declarations
-
-Add to syntax
-
-        type_definition ::= ... | interface_type_definition
-
-
-
-3.4 Derived Types and Classes
-
-Replace syntax section with
-
-        interface_list ::= interface_subtype_mark {AND interface_subtype_mark}
-
-        derived_type_definition ::=
-            [ABSTRACT] NEW parent_subtype_indication
-            [[AND interface_list] record_extension_part]
-
-
-Add at the end of paragraph 3:
-
-    A derived type has one parent type and zero or more interface ancestor types.
-
-Replace paragraph 8 with:
-
-    Each class of types that includes the parent type or an interface ancestor
-    type also includes the derived type.
-
-Add after paragraph 25:
-
-    If a type declaration names an interface type in an interface list, then
-    the declared type inherits any user-defined primitive subprograms of the
-    interface type in the same way.
-
-Add after paragraph 35 (in the Notes section):
-
-    18 An interface type which has an interface ancestor "is derived from"
-    that type, but it is not "a derived type". Conversely, a derived
-    type is never an interface type.
-
-3.4.1 Derivation Classes
-
-Insert after the first sentence of paragraph 2:
-
-     A derived type or interface type is also derived from each of its
-     interface ancestor types, if any.
-
-Replace the last sentence of paragraph 10 with:
-
-    The ultimate ancestor of a type is the ancestor of that type, if any, that
-    is not a descendant of any other type and that is not an interface
-    type (see 3.9.4).
-
-
-3.9.3 Abstract Types and Subprograms
-
-    Replace paragraphs 4-5 with
-
-        If a type inherits a subprogram corresponding to an abstract
-        subprogram or to a function with a controlling result, then
-
-           - If the inheriting type is abstract or untagged, the inherited
-             subprogram is abstract.
-
-
-3.9.4 Interface Types
-
-    This section is entirely new.
-
-        An interface type is an abstract tagged type intended for use
-        in providing a restricted form of multiple inheritance.
-        A tagged type may be derived from multiple interface types.
-
-                                 Syntax
-
-        interface_type_definition ::= [LIMITED] INTERFACE [WITH interface_list]
-
-                                 Legality Rules
-
-        An interface type (also called an "interface") is a specific abstract
-        tagged type that is defined by an interface_type_definition.
-
-        An interface type shall have no components.
-
-        All user-defined primitive subprograms of an interface type shall be
-        abstract subprograms or null procedures.
-
-        The type of a subtype named in an interface_list shall be an
-        interface type.
-
-        If a type declaration names an interface type in an interface list,
-        then the accessibility level of the declared type shall not be
-        statically deeper than that of the interface type; also, the declared
-        type shall not be declared in a generic body if the interface type is
-        declared outside that body.
-
-        A descendant of an interface type shall be limited if and only
-        if the interface type is limited.
-
-        A full view shall be a descendant of an interface type if and only if
-        the  corresponding partial view (if any) is also a descendant of the
-        interface type.
-
-        For an interface type declared in a visible part, a primitive
-        subprogram shall not be declared in the private part.
-
-        In addition to the places where Legality Rules normally apply
-        (see 12.3), these rules apply also in the private part of an instance
-        of a generic unit.
-
-4.5.2  Relational Operators and Membership Tests
-
-    Replace paragraph 3 with
-
-        The tested type of a membership test is the type of the range or the
-        type determined by the subtype_mark. If the tested type is tagged,
-        then the simple_expression shall resolve to be of a type that is
-        convertible (see 4.6) to the tested type; if untagged, the expected
-        type for the simple_expression is the tested type.
-
-4.6 Type Conversions
-
-    Replace paragraphs 21-23 with
-
-        If the target type is tagged then either:
+   bodies would be executed. The two conversions to Pkg.Ifc'Class
+   would map Pkg.Foo to different slots in the same dispatch table
+   because the source types of the conversions are different.
 
-            - The operand type shall be covered by or descended from the target
-              type; or
+   We want to prevent this sort of thing.
 
-            - The operand type shall be a class-wide type that covers the
-              target type; or
+4) A type derived from an interface type should inherit the same subprograms
+   as a type which is derived from both the interface type and an ancestor of
+   the interface type. The two type definitions should be indistinguishable,
+   in the sense that adding or deleting the explicit redundant derivation
+   relationship should be a semantics-preserving transformation.
 
-            - The operand and target types shall both be class-wide types and
-              the specific type associated with at least one of them shall
-              be an interface type.
+5) It is intended that there should be no real difference between the two
+   forms of derivation from interface types. For example, replacing
+   the declaration
+       type T is new Interface_Type_1 and Interface_Type_2 with null record;
+   with
+       type T is new Interface_Type_2 and Interface_Type_1 with null record;
+   should be semantics-preserving.
 
-        If the target type is not included in any of the above five cases,
-        there shall be a type that is an ancestor of both the target type
-        and the operand type.
+6) Someone asked why an interface type declared in a visible part is not
+   allowed to have primitive operations declared in the private part.
+   A dispatching call to a primitive of an interface type will execute
+   the body of a corresponding routine associated with the specific type
+   of the controlling operand. Without this restriction, it is possible that
+   the specific type might provide no such routine. It would be ok to follow
+   the example of 3.9.3(10) and allow this in the case where the subprogram
+   declared in the private part "is overriding an abstract subprogram
+   implicitly declared in the visible part", but this doesn't seem to be
+   worth the bother because this could only be used to override an abstract
+   procedure with a null procedure. There does not appear to be universal
+   agreement on this point.
 
-6.1  Subprogram Declarations
+7) Someone asked why a limited interface cannot be implemented by a
+   non-limited type. An implementation would no longer know statically
+   whether a dispatching function call is a call to a function with a
+   return-by-reference result. This could be implemented, but it seems
+   like an unnecessary complication. The language has, as a matter of
+   general principle, steered away from constructs which would allow a
+   limited view of an object of a non-limited tagged type.
 
-Replace
-   subprogram_specification ::= PROCEDURE defining_program_unit_name
-                                          parameter_profile
-with
-   procedure_specification ::= PROCEDURE defining_program_unit_name
-                                         parameter_profile
-   subprogram_specification ::= procedure_specification
+8) It is intended that in the case where the implementation
+   arbitrarily chooses one overrider from among a group of inherited
+   subprograms, users should be unable to determine which
+   member was chosen. The "one is chosen arbitrarily to override the others"
+   monkey business in 8.3 is needed in order to allow
 
+      package Outer is
+        package P1 is
+           type Ifc1 is interface;
+           procedure Null_Procedure (X : Ifc1) is null;
+           procedure Abstract_Subp  (X : Ifc1) is abstract;
+         end P1;
 
-7.3 Private Types and Private Extensions
+         package P2  is
+           type Ifc2  is interface;
+           procedure Null_Procedure (X : Ifc2) is null;
+           procedure Abstract_Subp  (X : Ifc2) is abstract;
+         end P2;
 
-    Replace
-        private_extension_declaration ::=
-          TYPE defining_identifier [discriminant_part] IS
-          [ABSTRACT] NEW ancestor_subtype_indication WITH PRIVATE;
-    with
-        private_extension_declaration ::=
-          TYPE defining_identifier [discriminant_part] IS
-          [ABSTRACT] NEW ancestor_subtype_indication
-          WITH [interface_list AND] PRIVATE;
+         type T is new P1.Ifc1 and P2.Ifc2 with null record;
+      end Outer;
 
+    without requiring that T explicitly override any of its inherited
+    operations. If requiring explicit overrides in this case is considered
+    to be ok, then that bit of oddness could be deleted from 8.3.
 
-8.3 Visibility
+    If it turns out that users can somehow determine which
+    member was chosen and that this approach introduces serious portability
+    problems, then one could impose an arbitrary-but-determininistic
+    tie-breaking scheme (e.g. make use of the order of the interface types,
+    prefering operators inherited from "earlier" types; in the above
+    example, this would mean that the operators inherited from P1.Ifc1
+    would override those inherited from P2.Ifc2).
 
-    Add after paragraph 12:
+!example
 
-        An implicit declaration of an inherited subprogram which is inherited
-        from a non-interface type overrides that of a subprogram
-        inherited from an interface type which is implicitly
-        declared at the same point.
+An example involving interface types:
 
-        If one subprogram overrides another and a type inherits subprograms
-        corresponding to both which are implicitly declared at the same point,
-        then the inherited subprogram corresponding to the overriding
-        subprogram overrides the other inherited subprogram.
+   type T is tagged null record;
+   T_Var : T;
 
-        If an inherited subprogram corresponds to another subprogram and a
-        type inherits subprograms corresponding to both which are implicitly
-        declared at the same point, then the subprogram corresponding to the
-        inherited subprogram overrides the other inherited subprogram.
+   package P1 is
+      type Ifc1 is interface;
+      procedure Op    (X : Ifc1) is abstract;
+      procedure Op1_A (X : Ifc1) is abstract;
+      procedure Op1_B (X : Ifc1) is abstract;
 
-        If a descendant of an interface type inherits two or more
-        fully conformant abstract or null subprograms which are
-        implicitly declared at the same point, and if the preceding rules
-        do not cause any of them to be overridden, then one of these
-        subprograms overrides the others; which one is unspecified, except
-        that an abstract subprogram shall not be chosen if a null subprogram
-        is available.
+      type Ref is access all Ifc1'Class;
+      Procedure Foo (X : Ref);
+   end;
 
-    Add after paragraph 26:
+   package P2 is
+      type Ifc2 is interface;
+      procedure Op    (X : Ifc2) is abstract;
+      procedure Op2_A (X : Ifc2) is abstract;
+      procedure Op2_B (X : Ifc2) is abstract;
 
-        If a descendant of an interface type inherits two homographs
-        which are implicitly declared at the same point, then at least one
-        shall be overridden.
+      type Ref is access all Ifc2'Class;
+      Procedure Foo (X : Ref);
+   end;
 
-12.5 Formal Types
+   package body P1 is
+      ...
 
-    Add to syntax
+      procedure Foo (X : Ref) is
+         type Stream_Ptr is access all Ada.Streams.Root_Stream_Type'Class;
+         The_Stream : constant Stream_Ptr := ...;
+      begin
+          Op1_A (X.all);
+          Op1_B (X.all);
+          Ifc1'Class'Output (The_Stream, X.all);
 
-        formal_type_declaration ::= ... | formal_interface_type_definition
+          if X.all in T'Class then
+              T_Var := T (X.all);
+          end if;
+      end Foo;
+   end P1;
 
+   package body P2 is
+      ...
+   end P2;
 
+   type D is tagged
+       with P1.Ifc1 and P2.Ifc2 and
+       record
+           F1, F2 : Integer;
+       end record;
 
-12.5.1 Formal Private Types
+   procedure Op1_A (X : D);
+   procedure Op1_B (X : D);
+   procedure Op    (X : D);
+   procedure Op2_A (X : D);
+   procedure Op2_B (X : D);
 
-    Replace
-        formal_derived_type_definition ::= [ABSTRACT] NEW subtype_mark
-                                           [WITH PRIVATE]
-    with
-        formal_derived_type_definition ::= [ABSTRACT] NEW subtype_mark
-                                           [WITH [interface_list AND] PRIVATE]
+   ...
 
+   X : aliased D;
+ begin
+   P1.Foo (X'Access);
+   P2.Foo (X'Access);
+   P1.Op (P1.Ifc1'Class (X));
+   P2.Op (P2.Ifc2'Class (X));
+ end;
 
-    Add after paragraph 15:
+ --------
 
-        The actual type shall be a descendant of every ancestor of
-        the formal type.
+ A somewhat less artificial example:
 
+     package Object_Monitoring is
+       type Monitored_Object is interface;
+       procedure Display (Object : Monitored_Object) is abstract;
 
-12.5.5 Formal Interface Types
+       type Object_Reference is access all Monitored_Object'Class;
+       for Object_Reference'Storage_Size use 0;
 
-    This section is entirely new.
+       procedure Register   (Object : Object_Reference);
+       procedure Unregister (Object : Object_Reference);
+       procedure Display_Registered_Objects;
+     end;
 
-        The class determined for a formal interface type is the class of all
-        interface types.
+     package body Object_Monitoring is
+       package Object_Reference_Sets is new ... ;
 
-                                 Syntax
+       Registered_Objects : Object_Reference_Sets.Set;
 
-        formal_interface_type_definition ::= interface_type_definition
+       procedure Display_One (Object : Object_Reference) is
+       begin
+         Display (Object.all);
+       end;
 
+       procedure Display_Registered_Objects is
+       begin
+          Object_Reference_Sets.Visit_All
+            (The_Set   => Registered_Objects,
+             Visit_One => Display_One'Access);
+       end;
 
-                                 Legality Rules
+       ...
+     end Object_Monitoring;
 
-        The actual type shall be a descendant of every ancestor of
-        the formal type.
+     package Pkg1 is
+        ...
+     end Pkg1;
 
-        The actual type shall be limited if and only if the formal type is
-        limited.
+     with Object_Monitoring;
+     package body Pkg1 is
+         type T is tagged record F1, F2 : Integer; end record;
 
-13.14 Freezing Rules
+         type Monitored_T is new T and Object_Monitoring.Monitored_Object
+             with ...;
 
-    Add after paragraph 7:
+         procedure Display (Object : Monitored_T) is begin ... end;
 
-        The declaration of a specific descendant of an interface type freezes
-        the interface type.
+         X : aliased Monitored_T;
 
+         ...
+      begin
+         Object_Monitoring.Register (X'access);
+      end;
 
 !ACATS test
 
+ACATS Tests should be constructed to test this feature.
+
 !appendix
 
 !from Tucker Taft
@@ -3923,6 +3949,112 @@
 
 [Editor's note: Most of the following discussion is on the concept of
 unreserved keywords, and is filed there (in AI-284).]
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, October 5, 2003  12:14 PM
+
+Wording about homograph hiding for AI-251:
+
+Two homographs are not generally allowed immediately within the same
+declarative region unless one overrides the other (see Legality Rules below).
+The only declarations that are overridable are the implicit declarations for
+predefined operators and inherited primitive subprograms. A declaration
+overrides another homograph that occurs immediately within the same declarative
+region in the following cases:
+
+* A declaration that is not overridable overrides one that is overridable,
+regardless of which declaration occurs first;
+
+* The implicit declaration of an inherited operator overrides that of a
+predefined operator;
+
+* An implicit declaration of an inherited subprogram overrides a previous
+implicit declaration of an inherited subprogram.
+
+* If two or more homographs are implicitly declared at the same place:
+
+   - At most one shall be a non-null non-abstract subprogram, and it
+     overrides all the others;
+
+   - If all are null procedures or abstract subprograms, then any null procedure
+     overrides all abstract subprograms; if more than one homograph remains that
+     is not thus overridden, then their profiles shall be fully conformant with
+     one another, and one is chosen arbitrarily to override the others.
+
+* For an implicit declaration of a primitive subprogram in a generic unit,
+there is a copy of this declaration in an instance. However, a whole new set of
+primitive subprograms is implicitly declared for each type declared within the
+visible part of the instance. These new declarations occur immediately after
+the type declaration, and override the copied ones. The copied ones can be
+called only from within the instance; the new ones can be called only from
+outside the instance, although for tagged types, the body of a new one can be
+executed by a call to an old one.
+
+****************************************************************
+
+From: Stephen W. Baird
+Sent: Wednesday, October 15, 2003  12:44 PM
+
+This version of AI-251 [Editor's note, this is version /09] incorporates the
+feedback from the Sydney ARG meeting.
+
+Significant changes include:
+
+    * Tuck's suggested wording changes for 8.3
+
+    * Syntax changes
+      - type T2 is new T1 with Ifc1 and null record;
+        becomes
+        type T2 is new T1 and Ifc1 with null record;
+
+      - type T2 is new T1 with Ifc1 and private;
+        becomes
+        type T2 is new T1 and Ifc1 with private;
+
+      - type IFc is interface with A and B;
+        becomes
+        type Ifc is interface A and B;
+
+    * An observation that this AI effectively implies that tag components
+      for all tagged types must reside at the same offset; user-specified
+      tag placement becomes much more difficult to support.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Wednesday, October 15, 2003  3:58 PM
+
+Steve,
+
+I have a couple of comments on the 8.3 wording:
+
+> 8.3 Visibility
+>
+> Replace paragraphs 9/1 - 13 with
+>
+> ...
+>       * If two or more homographs are implicitly declared at the same place:
+>
+>         - At most one shall be a non-null non-abstract subprogram, and it
+>           overrides all the others;
+
+Remove the hyphens for consistency with RM style (nonnull, nonabstract).
+
+>         - If all are null procedures or abstract subprograms, then any null
+>           procedure overrides all abstract subprograms; if more than one
+>           homograph remains that is not thus overridden, then their profiles
+>           shall be fully conformant with one another, and one is chosen
+>           arbitrarily to override the others.
+
+Both of the above bulleted paragraphs contain legality wording
+(the uses of "shall"), but until now this set of paragraphs has
+been classified strictly as static semantics.  That seems like
+a problematic departure from the current structure and needs
+to be resolved somehow.  In the present version of 8.3, legality
+rules only appear in 8.3(26/1) (plus the Name Resolution rules
+in 24-25).
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent