CVS difference for ais/ai-00251.txt

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

--- ais/ai-00251.txt	2003/02/01 04:40:34	1.11
+++ ais/ai-00251.txt	2003/05/24 00:00:22	1.12
@@ -1,4 +1,4 @@
-!standard 03.04    (02)                            02-09-27  AI95-00251/06
+!standard 03.04    (02)                            03-05-23  AI95-00251/07
 !standard 03.09.01 (02)
 !class amendment 00-12-04
 !status work item 00-12-04
@@ -9,11 +9,13 @@
 
 !summary
 
-This proposal adds "interface" types to the standard. A tagged type may
-"implement" one or more such interfaces. The classwide type associated with the
-interface "covers" all types that implement it. Dispatching calls through the
-primitives of the interface type dispatch to code bodies associated with
-specific tagged types that implement the interface.
+This proposal adds "interface" types to the standard as a kind of
+componentless abstract tagged type. A tagged type may be
+derived from one or more such interfaces; this provides a limited form
+of multiple inheritance. The classwide type associated with
+the interface "covers" all types that implement it. Dispatching calls through
+the primitives of the interface type dispatch to code bodies associated with
+specific tagged types that are derived from the interface.
 
 !problem
 
@@ -43,168 +45,43 @@
 
 !proposal
 
-The following syntactic changes are proposed to support abstract interface types:
+An interface type is a new kind of componentless abstract tagged type.
 
-   type_definition ::= ... | abstract_interface_definition
-
-   abstract_interface_definition ::= ABSTRACT [LIMITED] INTERFACE
-
-   derived_type_definition ::=
-     [ABSTRACT] NEW parent_subtype_indication
-       [AND abstract_interface_list]
-       [record_extension_part]
-
-   abstract_interface_list ::=
-     abstract_interface_subtype_mark {AND abstract_interface_subtype_mark}
-
-   private_extension_declaration ::=
-     ... [ABSTRACT] NEW ancestor_subtype_indication
-       [AND abstract_interface_list] WITH PRIVATE;
+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.
 
-   formal_type_definition ::= ... | formal_abstract_interface_definition
+The primitive subprograms of an interface type must either be abstract
+or "null". A "null" procedure is a procedure declaration of the (newly
+introduced) form
 
-   formal_abstract_interface_definition ::=
-       abstract_interface_definition
+     procedure P (...) is null;
 
-   formal_derived_type_definition ::=
-     [ABSTRACT] NEW ancestor_subtype_indication
-       [AND abstract_interface_list] [WITH PRIVATE];
+whose dynamic semantics are similar to a procedure with the body
 
-  NOTE: we plan to make "INTERFACE" an unreserved keyword, to minimize
-  upward incompatibility.  The current term "reserved word" will
-  probably become something like "keyword", which can be either
-  "reserved" or "unreserved."  Most new users need not be aware of
-  the distinction, and will probably treat all keywords as reserved.
-
-An abstract interface type (or "interface" for short) is defined by an
-abstract_interface_definition or by a derived_type_definition where the word
-ABSTRACT appears, the parent type is an interface, and there is no
-record_extension_part. A formal abstract interface type is defined by a
-formal_abstract_interface_definition, or a formal_derived_type_definition with
-the word ABSTRACT but without the words "WITH PRIVATE." An abstract interface
-type may not have discriminants (though tagged types that implement it may of
-course have them).
+     procedure P (...) is
+     begin
+         null;
+     end;
 
-All primitive operations of an abstract interface type must be declared
-abstract or "is null" (see below). Only abstract interface types may
-be mentioned in an abstract_interface_list.
+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.
 
-A tagged type may declare that it "implements" an interface by mentioning it
-after the reserved word "NEW" or "AND". Note that a tagged type defined by a
-derived_type_definition must include a record_extension_part.
-
-If an interface mentions other abstract interface types in its definition
-(after the reserved word NEW or AND), then any type that implements this new
-interface must also implement these other interfaces.  The new interface is
-also said to "implement" the other interfaces that it mentions.  An interface
-"implements" itself as well.  Finally, a tagged type "implements" all of its
-ancestor tagged types, including itself.
-
-Similarly, a private extension or formal derived type "implements" all of the
-types mentioned after the word NEW or AND.
-
-Note that we allow an abstract interface type as the parent type of a record
-extension or a private extension to simplify the syntax, and to allow an
-abstract interface type and an abstract tagged type to be used in a very
-similar fashion. This allows one to switch from an abstract tagged type to an
-abstract interface type during maintenance without significant disruption.
-
-If the reserved word LIMITED appears in an abstract_interface_definition, the
-interface is a limited interface, and assignment and equality are not available
-on its classwide type; otherwise it is a nonlimited interface. A nonlimited
-type may implement a limited interface, but not vice-versa. A derived type is
-limited if and only if its parent type is limited.
+In previous discussions (and in the discussion of the problem, above),
+there have been references to a specific type "implementing" an interface
+type. In this sense, a specific type can be thought of as "implementing"
+an interface if it is derived from that interface.
+This terminology ("implementing an interface") is not used in the RM wording,
+but it is useful for purposes of discussion.
 
-A formal derived type without the words "WITH PRIVATE" but with the word
-"ABSTRACT" is called a "formal derived interface".
+A private extension may be derived from an interface type as well; the
+complete view and the partial view of a type must agree with respect to
+the set of interfaces they "implement".
 
-In a generic instantiation, for a formal derived type, the actual must
-implement all of the types that the formal implements.  Furthermore, if the
-formal is not abstract, then the actual must not be abstract (and hence not an
-interface). Finally, if the formal is a formal derived interface, then the
-actual must be an abstract interface type.
-
-If the actual type is an interface, the formal must be an interface or a formal
-derived type with no non-interface ancestors. The formal may not be an
-abstract private tagged type, as this may create difficulties for shared
-generic implementation. This restriction does to some extent run counter to
-the goal of simplifying changing an abstract tagged type into being an abstract
-interface type during maintenance.
-
-In a package with a private extension declaration in its visible part, the full
-type must be a record extension that implements all of the types implemented by
-the private extension.
-
-A private extension or private tagged type must implement all the
-interfaces implemented by its full view.  In other words, the full
-view may not implement additional "private" interfaces.  This is to
-prevent the descendants of the partial view from unintentionally "stepping"
-on the implementations of the primitive operations of a privately
-inherited interface.
-
-A type that implements (directly or indirectly) an interface inherits the
-interface's (abstract) primitive operations with the usual substitution of the
-new type for the abstract interface type in their profile. If a type inherits
-multiple primitive subprograms that are homographs of one another, they must be
-subtype conformant with one another.  Also, a non-abstract inherited subprogram
-overrides any abstract ones, and if they are all abstract, they must be fully
-conformant with one another or be overridden [so the formal parameter names and
-defaults are well-defined].  If a type is non-abstract, and it inherits any
-abstract primitives that are not overridden by inherited non-abstract ones, it
-also must (as usual) override them.
-
-The 'Class attribute is defined for abstract interface types. The classwide
-type associated with an interface "covers" all types that implement it, and
-their associated classwide types. Conversions are permitted between (the
-classwide type of) any descendant of a type that implements an interface and
-the classwide type of the interface.  Converting to a covered type generally
-requires a tag check. A classwide type associated with an interface is
-considered a non-abstract, tagged, indefinite type, and matches generic formals
-in the same way as a classwide type of a "normal" tagged type.
-
-Membership tests are permitted where the operand's type covers the tested type.
-The 'Tag attribute is defined for abstract interface types, and uniquely
-identifies the interface from any other type or interface, except that for an
-interface declared within a task body or subprogram, the same value for 'Tag
-may be used for all elaborations of the declaration.
-
-In an extension aggregate, the name of the parent type may be used prior to the
-word "WITH" even if it is an interface. If it is an interface, there are
-necessarily no components to be default initialized. This facilitates moving
-from an abstract tagged type to an abstract interface type. Alternatively, a
-normal record aggregate may be used, taking advantage of the fact that the
-parent interface has no components.
-
-        "Null" Primitives
-
-   basic_declaration ::= ... | null_subprogram_declaration
-
-   null_subprogram_declaration ::= subprogram_specification IS NULL;
-
-As part of this proposal we include an ability to declare a
-primitive procedure using "is null" rather than "is abstract."
-This would be permitted for interfaces, as well as other types.
-The semantics of this would be that the body of the procedure is
-defined to be "is begin null; end;".
-
-If an interface has a null (i.e. non-abstract) primitive, then an abstract
-generic formal extension of the interface is only matched by types that have
-non-abstract implementations of this primitive. This allows non-dispatching
-calls on the primitive of the generic formal type to be made inside the
-generic, which may be necessary to enable a pass-the-buck-to-the-parent
-paradigm when overriding the operation. This is the paradigm used for
-finalization, for example, and is quite common in type hierarchies in general.
-
-Upon inheritance, a non-null inherited primitive overrides any null or abstract
-inherited primitives. If one or more null primitives are inherited, and no
-non-null, non-abstract primitives, then the null primitives must all be fully
-conforming (so they have the same formal parameter names and defaults), and the
-resulting inherited primitive is null. And of course, a non-dispatching call
-is permitted on a null, as opposed to abstract, primitive of an interface
-(which is really only useful in generics).
+Formal interface types are added to the language.
 
-Note that only dispatching calls are permitted on the non-null primitives of an
-interface, since they are necessarily abstract.
+See the Wording section for details.
 
 !discussion
 
@@ -306,6 +183,19 @@
 operation is null. These advantages exist independently of this proposal for
 interfaces.
 
+Like an instantiation, a null procedure is not allowed as a completion.
+Allowing this would double the amount of RM text needed for no real gain.
+
+A null procedure may have OUT-mode parameters, the same as a
+conventional "begin null; end;" procedure. There doesn't seem to be any
+reason to require an incompatiblity here.
+
+Having null procedures, it may make sense to change the spec of
+Ada.Finalization to define Initialize, Finalize, and Adjust as null procedures.
+7.6(9) does this in words currently, and it makes sense to use this feature
+to make that definition more explicit.
+
+
         Possible Implementation Model
 
 A possible implementation model for an interface "view" of an object is to use
@@ -399,151 +289,416 @@
 or more interfaces would also have to use fat pointers, even though both words
 would point to the same dispatch table.
 
+----
+
+1) The compatibility rules for membership testing could be tightened to
+   filter out more cases where the result of a membership test could not
+   possibly be True. The two types could be required to agree with respect to
+   limitedness, accessibility level, and/or set of enclosing generic bodies
+   (with a recheck generic spec rule as well). Do we want all this in a
+   name resolution rule? I'd say no.
+
+2) "Potentially share descendants" seems like an awkward term.
+    How about "weakly compatible"? "Potentially intersecting"?
+    "Potentially convertible"? The idea here is that we want to allow any
+    membership tests where the answer is not known statically. This includes
+    a case like
+
+       type T1 is tagged null record;
+       type T2 is interface;
+
+       X1 : T1'Class := ... ;
+       X2 : T2'Class := ... ;
+
+       Flag : Boolean := (X1 in T2'Class) and (X2 in T1'Class);
+
+   because of the possibility of a type which is descended from both
+   T1 and T2, e.g.
+       type T3 is new T1 and T2 with null record;
+   .
+
+3) It might be possible to express the legality rules for type conversions more
+   concisely. Would it be equivalent to replace the 3 listed conditions with
+            - The operand type descended from the target type; or
+            - The operand and target types shall potentially share descendants.
+   ?
+
+4) What representation attributes does an interface type have?
+   Can values for these attributes be specified?
+   What do T'Size and T'Alignment mean for any abstract type, not
+   just for interface types?
+
+5) Although an interface type which has an interface parent "is derived from"
+   that type, it is not "a derived type".
+
+6) Inherited homographs must be overridden. If the homographs are
+   not mode-conformant, then this may be impossible. Life's hard.
+
+7) Nothing here (in particular, nothing in the 8.3 stuff) is intended to
+   change the semantics of a program which declares no interface types.
+
+8) 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;
+
+           type D is new Some_Tagged_Type and P1.T1 and P2.T2 with null record;
+
+       D inherits procedures P'4, P'5, and P'6, corresponding to
+       P'1, P'2, and P'3, respectively.
+
+       Since P'3 overides P'2, P'6 overrides P'5 by the "overriding is
+       preserved by inheritance" rule.
+
+       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.
+
+9) Yes, it really is illegal if the parent type of a "with private"
+   type'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.
+
+   Relaxing the rule that a partial view must be derived from the same
+   interfaces as the completion is derived from is not out of the question, but
+   it could open the door for some very peculiar situations. If this example,
+
+        package P is
+          packge Pkg is
+              type Ifc is interface;
+              procedure Foo (X : Ifc) is abstract;
+          end;
+
+          type Parent_1 is tagged null record;
+
+          type T1 is new Parent_1 with private;
+        private
+          type Parent_2 is new Parent_1 and Pkg.Ifc with null record;
+          procedure Foo (X : Parent_2); -- Foo #1
+
+          type T1 is new Parent_2 with null record;
+        end;
+
+        with P;
+        package P_Client is
+          type T2 is new P.T1 and P.Pkg.Ifc with null record;
+          procedure Foo (X : T2); -- Foo #2
+          X : T2;
+        end P2_Client;
+
+        with P_Client;
+        package body P is
+          ...
+        begin
+          Pkg.Foo (Pkg.Ifc'Class (P_Client.X));
+             -- call Foo #2
+          Pkg.Foo (Pkg.Ifc'Class (T1 (P_Client.X)));
+             -- call Foo #1
+        end P2;
+
+   , were legal (it is illegal because the completion of T1 is descended
+   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.
+
+
+--------
+
+In defining interface types, a couple of design decisions seem to be
+of interest.
+
+First, there is the question of whether interface types should
+be a whole new class of type or a special kind of abstract tagged
+type. Since interface types have to abide by all of the restrictions
+of an abstract tagged type, the former approach would have involved
+a lot of repetition. The latter approach was chosen.
+
+Second, there is the question of derivation and operator inheritance.
+If a type "implements" an interface, then it must inherit operators
+from the interface type in order to override them. In an earlier version
+of this AI, the "implementing" type was not considered to be derived from the
+parent interface type and operator inheritance was accomplished via
+a separate mechanism. Now, a type which implements an interface type
+is defined to be derived from the interface type, thereby simplifying the
+operator inheritance rules and the definitions of terms such as
+"ancestor", "descendant", and "cover". This means that a given type may
+be immediately derived from more than one type, but at most one of them
+can be a non-interface type. It is no longer the case that every type
+has an "ultimate ancestor", but the term remains well-defined in all the
+cases where it is used in the reference manual.
+
+The rules for type conversion and membership testing need revision to
+cope with the possibility that an interface type and a tagged type
+might have a common descendant even though statically available information
+suggests no relationship between the two types.
+
+As an implementation model, one can think of a type which
+inherits operations from an interface type as defining a
+mapping from the primitive operations of the interface type (perhaps
+represented as dispatch table slot numbers) to those of the inheriting type.
+A dispatching call to an operation of an interface type is than accomplished
+by mapping the the called operation to the corresponding
+operation of the controlling operand's type. Alternatively, one
+might construct a separate dispatch table representing this
+alternative "view" of the "real" dispatch table, but that would
+require more work when deriving from a type which implements
+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
+be represented at runtime as a record address paired with a
+reference to this dispatch table permutation map.
+
+Classwide streaming operations for interface types require
+some care. Consider the case of a call to Some_Interface_Type'Class'Input
+occuring as the controlling operand of a dispatching call. The
+implementation must be able to determine where to dispatch to in this case.
+Membership testing may also require maintaining additional information
+at runtime.
+
+It is intended that a type which is 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.
+
+It is intended that there should be no real difference between the two
+forms of derivation from interface type parents. 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.
+
+
 !example
 
-        type Stack is abstract interface; -- An abstract interface type
-        procedure Append (S : in out Stack; E : Elem) is abstract;
-        function Length (S : Stack) return Natural is abstract;
-        procedure Remove_Last (S : in out Stack; E : out Element) is abstract;
-
-        type Queue is abstract interface; -- Another interface.
-        function Length (Q : Queue) return Natural is abstract;
-        procedure Append (Q : in out Queue; E : Elem) is abstract;
-        procedure Remove_First (Q : in out Queue; E : out Element) is abstract;
-
-        . . .
-        type Deque is abstract new Queue and Stack;
-                        -- An interface which inherits from both
-                        -- the Queue and Stack interfaces.
-        procedure Prepend (Q : in out Deque; E : Elem) is abstract;
-        procedure Remove_Last (Q : in out Deque; E : out Elem) is abstract;
-
-        . . .
-        type My_Deque is new Deque with private;
-                        -- A private extension that implements an interface
-private
-        type My_Deque is new Blob and Deque with record
-                        -- Conventional type implementing an interface.
-                . . .
-        end record;
+An example involving interface types:
 
-!wording
+   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;
 
-[Editor's note: The discussion and proposal sections have not been updated
-to match this wording.]
+!wording
 
 In 3.1 add
+
     basic_declaration ::= ... | null_procedure_declaration
 
+
+3.2.1 Type Declarations
+
+Add to syntax
 
-In 3.2.1 add
-    type_definition ::= ... | interface_type_definition
+        type_definition ::= ... | interface_type_definition
 
 
-Add after 3.4(23)
-    A type that implements an interface type (see 3.9.4) inherits
-    subprograms from the interface type, in the same way as for a type
-    derived from the interface type.
 
+3.4 Derived Types and Classes
 
-Add after the first sentence of 3.4.1(9):
-    If a type T1 implements an interface type T2 (see 3.9.4),
-    then T2'Class also covers all types covered by T1'Class.
+Replace syntax section with
 
-In 3.9.1(2), replace
-    record_extension_part ::= WITH record_definition
-with
-    record_extension_part ::= WITH [interface_list AND] record_definition
+        interface_list ::= interface_subtype_mark {AND interface_subtype_mark}
 
-In 3.9.1(3), add between sentences 3 and 4:
-    The accessibilty level (see 3.10.2) of a type that implements an
-    interface type (see 3.9.4) shall not be statically deeper than
-    that of the interface type.
-
-In 3.9.1(4), add after sentence 1:
-    An interface type shall not be implemented in a generic body if the
-    interface type is declared outside that body.
-
-Add after 3.9.3(6):
-    Corresponding rules apply for a type that inherits an abstract
-    subprogram by implementing an interface type (see 3.9.4, 3.4).
-
-Add a new subclause after 3.9.3:
-3.9.4  Interface Types
-    An interface type is an abstract tagged type intended for use
-    in providing a restricted form of multiple inheritance.
-    A tagged type may "implement" multiple interfaces, thereby allowing
-    multiple views of objects of the type.
-
-                             Syntax
-    interface_type_definition ::= [LIMITED] INTERFACE [WITH interface_list]
-    interface_list ::= interface_subtype_mark {AND interface_subtype_mark}
-
-    An interface type (also called an "interface") is a specific abstract
-    tagged type that is defined by an interface_type_definition.
-    [An interface type has no components.]
-
-                             Legality Rules
-
-    All primitive operations 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.
-
-    A type that implements an interface shall be limited if and only
-    if the interface type is limited.
-
-    If a partial view defines an interface type, then the corresponding
-    full view shall define an interface type.
-
-    If a full view implements an interface, then the corresponding
-    partial view (if any) shall implement the interface.
-
-    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.
-
-                             Static Semantics
-
-    A descendant of a type that names an interface type in an
-    interface_list, or that is derived from an interface type,
-    is said to "implement" the interface and any other interfaces
-    implemented by that interface.
-    A class-wide type implements the interfaces implemented by the
-    corresponding specific type. The corresponding full view of a
-    partial view of a type implements all interfaces implemented by
-    the partial view.
-
-In 4.5.2(13), replace:
-    Two access-to-subprogram values are unequal if they designate different
-    subprograms. [It is unspecified whether two access
-    values that designate the same subprogram but are the result of distinct
-    evaluations of Access attribute_references are equal or unequal.]
-with
-    Two access-to-subprogram values are unequal if they designate different
-    non-null subprograms. [It is unspecified whether two access
-    values that designate the same subprogram but are the result of distinct
-    evaluations of Access attribute_references are equal or unequal. It is
-    also unspecified whether two access values that designate different null
-    subprograms are equal or unequal.]
+        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 a parent type and zero or more interface parent types.
+
+
+
+Replace paragraph 8 with:
+
+    Each class of types that includes the parent type or an interface parent
+    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.
+
+    Note: this includes some declarations of non-derived types.
+
+
+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 parent 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 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, thereby
+        allowing multiple views of objects of the type.
+
+                                 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
+
+                                Name Resolution
+
+        Two types are said to "potentially share descendants" either if one
+        covers the other or if both are class-wide and the corresponding
+        specific type associated with at least one is an interface type.
 
-Replace 4.6(21-23) with:
+        The simple_expression shall resolve to be of a type that potentially
+        shares descendants with the tested type.
+
+4.6 Type Conversions
+
+        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
 
-  If the target type is tagged, then either:
+            - The operand and target types shall potentially share descendants.
 
-    The operand type shall be covered by or descended from the target type; or
+        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.
 
-    The operand type shall be a class-wide type that covers the target 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
 
-In 6.1 replace
+Replace
    subprogram_specification ::= PROCEDURE defining_program_unit_name
                                           parameter_profile
 with
@@ -551,9 +706,8 @@
                                          parameter_profile
    subprogram_specification ::= procedure_specification
 
-Add a new subclause after 6.6:
 
-Null Procedures
+6.7  Null Procedures
 
                               Syntax
 
@@ -566,75 +720,104 @@
                               Dynamic Semantics
 
     The execution of a null procedure is invoked by a subprogram call.
-    This execution has no effect.
+    The execution of the subprogram_body of a null procedure has no
+    effect.
+
+
+7.3 Private Types and Private Extensions
 
-In 7.3, replace
+    Replace
         private_extension_declaration ::=
-          type defining_identifier [discriminant_part] is
+          TYPE defining_identifier [discriminant_part] IS
           [ABSTRACT] NEW ancestor_subtype_indication WITH PRIVATE;
-with
+    with
         private_extension_declaration ::=
-          type defining_identifier [discriminant_part] is
+          TYPE defining_identifier [discriminant_part] IS
           [ABSTRACT] NEW ancestor_subtype_indication
           WITH [interface_list AND] PRIVATE;
 
-Add after paragraph 8.3(12):
 
-    An implicit declaration of an inherited subprogram which is neither
-    abstract nor a null procedure overrides that of a subprogram
-    inherited by implementing an interface that is implicitly
-    declared at the same place.
-
-    If one subprogram overrides another and a type inherits subprograms
-    corresponding to both that are implicitly declared at the same place,
-    then the inherited subprogram corresponding to the overriding
-    subprogram overrides the other inherited subprogram.
-
-    If an inherited subprogram corresponds to another subprogram and a
-    type inherits subprograms corresponding to both that are implicitly
-    declared at the same place, then the subprogram corresponding to the
-    inherited subprogram overrides the other inherited subprogram.
-
-    If a type that implements an interface inherits two or more
-    fully conformant abstract subprograms, or two or more fully
-    conformant null subprograms, that are implicitly declared
-    at the same place, and if the preceding rules would not specify
-    any overriding relationships among these subprograms, then
-    the implementation shall select one of these subprograms and it
-    shall override the others.
-
-In 12.5, add
-    formal_type_declaration ::= ... | formal_interface_type_definition
-
-In 12.5.1, 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]
+8.3 Visibility
 
-Add after 12.5.1(18):
-    The actual type shall implement any interfaces that are implemented by
-    the formal type.
+    Add after paragraph 12:
+
+        An implicit declaration of an inherited subprogram which is neither
+        abstract nor a null procedure overrides that of a subprogram
+        inherited from an interface type which is implicitly
+        declared at the same point.
+
+        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.
+
+        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.
+
 
-Add a new subclause after 12.5.4:
+    Add after paragraph 26:
+
+        If a descendant of an interface type inherits two homographs
+        which are implicitly declared at the same point, then both shall
+        be overridden.
+
+        Note: this requirement may be impossible to satisfy if the homographs
+        are not mode-conformant.
+
+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
+                                           [WITH [interface_list AND] 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.
+        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 implement any interfaces that are implemented by
-   the formal type.
+
+        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.
 
-   The actual type shall be limited if and only if the formal type is limited.
+13.14 Freezing Rules
 
-Add after 13.14(7):
-   The implementation of an interface causes freezing of the interface type.
+    Add after paragraph 7:
 
+        The declaration of a specific descendant of an interface type freezes
+        the interface type.
+
+
 !ACATS test
 
 !appendix
@@ -3100,6 +3283,36 @@
    P1.Op (P1.Ifc1'Class (X));
    P2.Op (P2.Ifc2'Class (X));
  end;
+
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, May 13, 2003  3:59 PM
+
+AI-251 introduces null procedures. Their dynamic semantics are
+specified as follows:
+
+    The execution of a null procedure is invoked by a subprogram call.
+    This execution has no effect.
+
+This seems wrong. This wording should be replaced with
+
+    The execution of a null procedure is invoked by a subprogram call.
+    The execution of the subprogram_body of a null procedure has no
+effect.
+.
+
+RM 6.3.2(10) breaks the execution of a subprogram call down into several
+steps. Calling a null procedure is different than calling a non-null
+procedure
+only with respect to the step "The subprogram body is then executed.". The
+other steps (evaluation of the name or prefix of the call, parameter
+evaluation,
+and parameter copy-back) are performed in the same way as for a non-null
+procedure.
+
+Elaboration checking is not an issue here because a null procedure cannot
+have a forward declaration.
 
 ****************************************************************
 

Questions? Ask the ACAA Technical Agent