CVS difference for ais/ai-10218.txt

Differences between 1.3 and version 1.4
Log of other versions for file ais/ai-10218.txt

--- ais/ai-10218.txt	2003/01/23 03:23:49	1.3
+++ ais/ai-10218.txt	2003/06/06 03:48:36	1.4
@@ -1,4 +1,4 @@
-!standard 8.3(26)                                    03-01-21  AI95-00218-02/03
+!standard 8.3(26)                                    03-04-28  AI95-00218-02/04
 !class amendment 00-09-30
 !status work item 02-09-30
 !status received 02-09-30
@@ -79,55 +79,91 @@
 that the programmer has declared all intentional overriding.
 
 Unfortunately, a complete solution to this problem would be incompatible with
-existing Ada 95 code. Therefore, we have to introduce an optional solution
-which applies only when the programmer asks for it.
+existing Ada 95 code. Therefore, we have to introduce a solution which permits
+backward compatibility and applies fully only when the programmer asks for it.
 
 Thus, we introduce a new pragma, Explicit_Overriding, and additional syntax
-with new nonreserved keywords which indicate that overriding will or might
+with a new nonreserved keyword which indicates that overriding will or might
 occur. Explicit_Overriding is a configuration pragma which requires use of
 the alternative syntax.
 
-Declarations that are overriding include "overrides" whereas those that
-might or might not be overriding (this situation can occur with generics
-and private types) include "maybe overrides". Subprogram declarations
-(other than those for visible operations of a private type) without this
-new syntax and to which pragma Explicit_Overriding applies are new
-declarations and must not override another routine. The same applies to
-renamings and generic instantiations.
+The general idea is that subprogram declarations that are overriding are
+prefixed with "overriding" whereas subprogram declarations without this new
+syntax must not override another routine. The same applies torenamings and
+generic instantiations. Special situations arise with generic packages and with
+private types.
+
+In the case of generics with a formal type it is possible that whether a
+declaration in the generic specification is overriding or not depends upon the
+actual type. In order to avoid imposing additional contract requirements such
+declarations may be prefixed by "overriding or not" in which case no check is
+made.
 
+The form "overriding or not" may in fact be used in all circumstances and has
+the effect of turning off the checking for that declaration.
+
 In the case of a subprogram which is a visible operation of a private type
-and which is marked "maybe overriding", it is permitted to redeclare the
-subprogram in the private part with an overriding indicator as necessary
-so that the checking can be performed when the full type is known.
+(or private extension), checking may occur twice, once for the partial
+view and again for the full view. It might be that the operation is
+not visibly overloaded but turns out to be overloaded when the full
+type declaration occurs. In this case the operation in the partial view
+is not prefixed by "overriding" but an overriding clause has to
+be given in the private part which consists essentially of a copy of the
+specification prefixed by "overriding" (or even "overriding or not"). This
+overriding clause has to have full conformance with the specification in
+the partial view and since such conformance is not defined for generic
+instances, the partial view may not be an instance.
+
+Note that if a declaration is prefixed by "overriding" then an appropriate
+check is always made (even in the absence of the pragma Explicit_Overriding)
+since it would be confusing for such explicit syntax to be ignored.
 
 !wording
 
 In 2.9(3) as modified by AI 284 add the following to the list of nonreserved
 keywords
 
-       maybe      overrides
+       overriding
 
 Change the syntax in 6.1 to read
 
-overriding_indicator ::= [maybe] overrides
+overriding_indicator ::= overriding [or not]
 subprogram_declaration ::=
-                subprogram specification [overriding_indicator];
+               [overriding_indicator] subprogram_specification ;
 abstract_subprogram_declaration ::=
-    subprogram specification [overriding_indicator] is abstract;
+   [overriding_indicator] subprogram_specification is abstract;
+overriding_clause ::= overriding_indicator subprogram_specification ;
 
 Add to 8.3 after paragraph 23:
 
-If an explicit declaration of a visible operation of a private type by
-a subprogram declaration, abstract subprogram declaration, subprogram
-renaming declaration or generic instantiation includes the overriding
-indicator "maybe overrides" then it is permitted to redeclare
-the operation in the corresponding private part by a subprogram declaration.
-Such a redeclaration shall occur following the corresponding
-full_type_declaration and shall be fully conformant with the declaration in
-the visible part; the redeclaration may include an overriding indicator.
+If an explicit declaration of a visible operation of a private type or
+a private extension by a subprogram_declaration,
+abstract_subprogram_declaration, or subprogram_renaming_declaration
+does not include the overriding_indicator "overriding" then it is
+permitted to give an overriding_clause for the operation in the
+corresponding private part.
+
+Such an overriding_clause shall occur following the corresponding
+full_type_declaration and before the type is frozen. Its profile shall be
+fully conformant with the profile of the subprogram_declaration,
+abstract_subprogram_declaration or subprogram_renaming_declaration.
 
 Add to 8.3 after paragraph 26:
 
+If an explicit declaration of a visible operation of a private type or private
+extension by a subprogram_declaration, abstract_subprogram_declaration,
+subprogram_renaming_declaration or generic_instantiation of a subprogram
+has the overriding_indicator "overriding" then it shall be an overriding
+declaration for the partial view of the type. If an overriding_clause has
+the overriding indicator "overriding" then the corresponding operation shall be
+an overriding operation for the full view of the type.
+
+If an explicit declaration of an operation of a type which is neither a private
+type nor a private extension by a subprogram_declaration,
+abstract_subprogram_declaration, subprogram_renaming_declaration or
+generic_instantiation of a subprogram has the overriding_indicator
+"overriding" then it shall be an overriding declaration for the type.
+
 The form of a pragma Explicit_Overriding is as follows:
 
 pragma Explicit_Overriding;
@@ -141,33 +177,35 @@
 
 At a place where a pragma Explicit_Overriding applies, an explicit
 subprogram_declaration, abstract_subprogram_declaration,
-subprogram_renaming_declaration or generic_instantiation of a subprogram
-without an overriding_indicator shall not be an overriding declaration whereas
-such a subprogram declaration with the overriding_indicator "overrides" shall
-be an overriding declaration. In addition to the places where Legality Rules
-normally apply, this rule also applies in the private part of an instance of a
-generic unit.
+subprogram_renaming_declaration or generic_instantiation of a subprogram
+without an overriding_indicator shall not be an overriding declaration for the
+view of the type at that place. Moreover, unless such a declaration of an
+operation of a private type given in the visible part has a corresponding
+overriding clause in the private part then it shall not be an overriding
+declaration for the full view of the type. In addition to the places where
+Legality Rules normally apply, these rules also apply in the private part
+of an instance of a generic unit.
+
+AARM Note:
+The overriding required by these rules does not necessarily need to happen
+immediately at the declaration of a primitive operation. It could occur later
+because of a later implicit declaration in the declarative region (see 7.3.1).
 
 Change the syntax in 8.5.4 to read
 
-subprogram_renaming_declaration ::= subprogram_specification
-                     [overriding_indicator] renames callable_entity_name;
+subprogram_renaming_declaration ::= [overriding_indicator]
+                  subprogram_specification renames callable_entity_name;
 
 Change the syntax in 12.3 to read
 
 generic_instantiation ::=
      package defining_program_unit_name is
         new generic_package_name [generic_actual_part];
-   | procedure defining_program_unit_name [overriding_indicator] is
+   | [overriding_indicator] procedure defining_program_unit_name is
         new generic_procedure_name [generic_actual_part];
-   | function defining_designator [overriding_indicator] is
+   | [overriding_indicator] function defining_designator is
         new generic_function_name [generic_actual_part];
 
-AARM Note:
-The overriding required by these rules does not necessarily need to happen
-immediately at the declaration of a primitive operation. It could occur later
-because of a later implicit declaration in the declarative region (see 7.3.1).
-
 !example
 
 Here is our original example using the new pragma and syntax.
@@ -177,9 +215,11 @@
 with Root;
 package Leaf is
    type Derived_Type is new Root.Root_Type with null record;
+   overriding
    procedure Do_Something (Object : in out Root_Type;
-                           Data : in Boolean) overrides;      -- Error:
-   procedure Finalise (Object : in out Root_Type) overrides;  -- Error:
+                           Data : in Boolean);           -- Error:
+   overriding
+   procedure Finalise (Object : in out Root_Type);       -- Error:
         -- Note: Alternative spelling of "Finalize".
 end Leaf;
 
@@ -189,21 +229,30 @@
 !discussion
 
 The configuration pragma Explicit_Overriding is necessary for backward
-compatibility. If the pragma is applied then the form "overrides" on
-subprogram declarations provides override checking even when no overriding
-subprograms are declared. This checking prevents accidental overriding.
-
-The form "maybe overrides" is required so that we can handle generic
-units and operations of private types where we cannot tell for sure
-whether overriding occurs. For instance, a mix-in generic does not
-care whether its operations override existing ones (the user of the
-generic may care, but that cannot be specified as part of the generic).
-Therefore, we provide "maybe overrides" as a "don't care" marker, so that
-projects can still use the pragma Explicit_Overriding even if such generics
-are included. The effect of "maybe overrides" can be thought of as
-restoring the Ada 95 rules for overriding for a particular declaration.
+compatibility. If the pragma is applied then the prefix "overriding" is
+required on all subprogram declarations that do override. This checking
+prevents accidental overriding. Similarly if the pragma is applied then any
+subprogram declaration which does not override must not have the prefix.
+
+If the pragma is not applied and the prefix is omitted then there is no check
+that the subprogram does not override. However, if the prefix is given then
+even in the absence of the pragma, a check is still made that the subprogram
+does override. This provides maximum benefit with backward compatibility. The
+possibility of simply using the pragma to disable all overriding checks was
+considered but dismissed on the grounds that it would be very surprising for
+the programmer to be able to write "overriding" and then for the compiler to
+ignore it.
+
+The form "overriding or not" is required so that we can handle generic units
+where we cannot tell for sure whether overriding occurs. For instance, a mix-in
+generic does not care whether its operations override existing ones (the user
+of the generic may care, but that cannot be specified as part of the generic).
+Therefore, we provide "overriding or not" as a "don't care" marker, so that
+projects can still use the pragma Explicit_Overriding even if such generics are
+included. The effect of "overriding or not" can be thought of as restoring the
+Ada 95 rules for overriding for a particular declaration.
 
-Note that the forms "overrides" and "maybe overrides" are part of a
+Note that the forms "overriding" and "overriding or not" are part of a
 subprogram declaration and not the subprogram specification. This is because
 we do not want them to be permitted in all syntactic situations which use
 subprogram specification such as generic subprogram declarations,
@@ -211,15 +260,23 @@
 them to apply to abstract subprograms, to renaming and to generic
 instantiations. For example
 
-   procedure Op(X: T) overrides is abstract;
+   overriding
+   procedure Op(X: T) is abstract;
 
-   procedure Pop(Y: TT) maybe overrides renames Pip;
+   overriding
+   procedure Pop(Y: TT) renames Pip;
 
-   procedure Pup overrides is new Pap(P1 => A1, P2 => A2);
+   overriding
+   procedure Pup is new Pap(P1 => A1, P2 => A2);
 
-One consequence is that we cannot use an overriding indicator with a
+Observe that we cannot use an overriding indicator with a
 subprogram body given alone but must supply a distinct subprogram
-declaration if we need to include one.
+declaration if we need to include one. Recall that in Ada 95, a subprogram
+body given alone in a package body can override an inherited primitive
+operation although it cannot be a new primitive operation. It would be
+surprising to permit the overriding indicator with such a body given alone
+since the existence of the overriding would not then be clear just from the
+package specification. This applies to both tagged and untagged types.
 
 Requiring the explicit declaration of overriding is used in some other
 programming languages, most notably Eiffel (which uses the keyword redefine).
@@ -232,78 +289,92 @@
 as it is normally the case that all of the inherited routines with a
 single name are overridden as a group.
 
-Implementing the checking of this feature takes some care, because an
-operation may become overriding at a later point (because of the rules of
-7.3.1(6)). A compiler always knows that such overriding will happen later,
-so this should not provide an implementation burden.
 
-An example of how this could happen:
+Subtle situations occur with generics and private types. We will consider
+generics first.
 
-pragma Explicit_Overriding;
+The pragma Explicit_Overriding and the "overriding" syntax are checked in a
+generic_declaration (as well as in instantiations). Consider
 
-package P is
-    type T is tagged private;
+generic
+    type GT is tagged private;
+package Gen is
+    type DGT is new GT with private;
+    overriding
+    procedure Op (Z : DGT); -- Error: Doesn't override anything.
 private
-    procedure Op (Y : T);
-end P;
+    -- ...
+end Gen;
 
-package P.C is
-    type NT is new T;
-    procedure Op (Y : NT) overrides; -- OK.
-    package Nested is
-        type NNT is new T;
-        procedure Op (Y : NNT); -- Illegal because the body of Nested has
-                                -- visibility on primitive 'Op'
-                                -- We must add "overrides"
-                                -- or "maybe overrides".
-    end Nested;
-private
-    -- P.C.Op overrides P.Op here (P.Op is inherited here).
-end P.C;
+If we didn't enforce the rule in generic_declarations (but only in
+instantiations), we could give "overriding" in this generic as shown.
+The effect would be to force all actual types for GT to have an operation Op.
+This would effectively modify the contract of the generic to include that
+operation.
 
-package body P.C is
-    package body Nested is
-        -- P.C.Nested.Op overrides P.Op here (P.Op is inherited here).
-    end Nested;
-end P.C;
+Of course, we could have said that the overriding checks are not applied in
+generic declarations so that the user can modify the contract in this way
+but this would have been at variance with the general language principle of
+applying all checks in a generic declaration and then checking again as
+necessary for each instantiation.
+
+As a consequence "overriding" can never be used on operations of aderivation of a generic formal private type (as in the example), as no
+primitive operations are inherited from the formal type. Thus we write
+"overriding or not" so that the instantiation can allow overriding. Thus
 
-Note the possibility of using "maybe overrides" in this example as indicated
-in the comment; it can be used here to avoid breaking the abstraction
-(privateness) of the original type P.T.
-
-The pragma Explicit_Overriding and the "overrides" syntax are checked in a
-generic_declaration (as well as in instantiations). We do this because we do
-not want the feature to be part of the "contract" of a generic and thereby
-add additional restrictions on the actual parameters of the generic.
-To see how this could happen, consider the following example:
+generic
+    type GT is tagged private;
+package Gen is
+    type DGT is new GT with private;
+    overriding or not
+    procedure Op (Z : DGT); -- OK: no checking done.
+                            -- can be instantiated with a type that
+                            -- does or does not already have Op
+private
+    -- ...
+end Gen;
+Observe that if no overriding indicator is given then the contract is changed
+since an instantiation which does indeed already have Op would be illegal. Thus
 
 generic
     type GT is tagged private;
 package Gen is
     type DGT is new GT with private;
-    procedure Op (Z : DGT) overrides; -- Error: Doesn't override anything.
+    procedure Op (Z : DGT); -- No overriding indicator
+                            -- cannot be instantiated with a type that
+                            -- already has Op
 private
     -- ...
 end Gen;
 
-If we didn't enforce the rule in generic_declarations (but only in
-instantiations), we could give "overrides" in this generic as shown.
-The effect would be to force all actual types for GT to have an operation Op.
-This would effectively modify the contract of the generic to include that
-operation.
+Note therefore that we can modify the contract to prevent
+overriding but not to require it.
 
-As a consequence "overrides" can never be used on operations of a
-derivation of a generic formal private type (as in the example), as no
-primitive operations are inherited from the formal type. This is not too
-serious, as "maybe overrides" can always be used to allow overriding.
+A related situation is where the formal type is derived so that there may be
+a number of known primitive operations. Consider
 
+generic
+    type GT is new T with private;
+package Gen is
+    type DGT is new GT with private;
+    overriding
+    procedure Op (Z : DGT); -- OK if T has Op as an operation.
+private
+    -- ...
+end Gen;
+
+If the type T has Op as an operation then we must give an overriding indicator
+(either "overriding" or "overriding or not"). The form "overriding or not" would
+be appropriate for the situation where T did not have Op as a primitive but
+that DT derived from T does have Op and the generic is instantiated with DT.
+
 Note that the only check required at instantiation is to recheck operations
-which have neither "overrides" nor "maybe overrides" to ensure
+which have neither "overriding" nor "overriding or not" to ensure
 that they do not override some inherited operation. The check in the
-generic_declaration is sufficient for "overrides", while "maybe overrides"
+generic_declaration is sufficient for "overriding", while "overriding or not"
 needs no check at all.
 
-A similar situation arises with private types. Thus consider
+A somewhat similar situation arises with private types. Thus consider
 
 package P is
    type T is private;
@@ -323,34 +394,161 @@
 
 The point is that the partial view does not reveal whether overriding
 occurs or not - nor should it since either implementation ought to be
-acceptable. We can therefore put "maybe overrides" on the declaration of
-"+" so that either implementation is possible. In order to permit checking when
-the full circumstances are known, we introduce the possibility of a
-redeclaration of the operation in the private part. The redeclaration may
-include an overriding indicator and is checked as appropriate. A redeclaration
-is only permitted when that in the visible part has the overriding indicator
-"maybe overrides" and naturally has to be fully conformant with it. Thus
+acceptable. We should therefore remain silent regarding overriding in the
+partial view. In order to permit checking when the full circumstances are
+known, we introduce the possibility of an overriding clause in the private
+part. This takes the form of an overriding indicator followed by a repetition
+of the subprogram specification whose profile has to be fully conformant with
+the profile given in the private view. An overriding clause is only necessary
+when the operation in the visible part does not have the overriding indicator
+"overriding" and in the full view the operation does override. Thus
 
 package P is
    type T is private;
-   function "+" (Left, Right: T) return T maybe overrides; -- don't know here
+   function "+" (Left, Right: T) return T; -- overriding not visible
 private
    type T is range 0 .. 100;
-   function "+" (Left, Right: T) return T overrides;  -- now we know
+   overriding
+   function "+" (Left, Right: T) return T;  -- now we know
+end P;
+
+Any overriding clause must occur before the type is frozen. Note that
+overriding is always checked for both the partial view and the full view.
+The form "overriding or not" is permitted for both views. An overriding
+clause can always be given even if not necessary.
+
+Note that full conformance is required between the profiles although it is
+not strictly necessary for identification purposes. However, permitting a
+lesser level might be confusing for the reader. Note moreover that the
+conformance rules required for overriding are different for tagged and
+untagged types (tagged require subtype conformance whereas untagged only
+require type conformance) so it seems a good idea to overkill with full
+conformance for both.
+
+An overriding clause may not be given in the case where the operation
+is provided by a generic instantiation. This is because conformance rules
+are not defined for the profile of an instantiation. There are other
+restrictions on generic instantiations such as that they are not allowed
+to complete a subprogram declaration and so this restriction should not
+seem surprising. As a consequence an instantiation cannot be used to provide
+an operation in the visible part if that operation turns out to be an
+overloading one and this is not so for the partial view. This is probably
+not a frequent situation. The workaround is to give the instantiation a
+different name and then to rename it as the primitive operation thus
+
+package P is
+   type T is private;
+   procedure Pup is new Pap(P1 => A1, P2 => A2);
+   procedure Op(Y: T) renames Pup;
+
+private
+   type T is new TT;          -- TT has an Op and so it overrides
+   overriding
+   procedure Op(Y: T);        -- the overriding clause on the renaming
+end P;
+
+Observe that if the partial view says "overriding" then it would be a
+burden to require an overriding clause in the full view as well (although
+it is permitted). However, if the partial view says "overriding or not" then
+the full view needs to be checked still and thus might require an overriding
+clause.
+
+Similar examples occur with private extensions
+
+package P is
+   type T is new T1 with private;
+   procedure Foo;
+private
+   type T is new T2 with ...;
+   overriding
+   procedure Foo;
 end P;
 
-Another similar example is
+This covers the situation where T1 does not have the operation Foo but T2
+(which of course is ultimately derived from T1) does have the operation.
 
+If T1 does have the operation Foo, then an overriding indicator must be
+given for the partial view. An overriding indicator can be given for the
+full view but is not necessary. Thus
+
 package P is
-   type T is new T1;
-   procedure Foo maybe overrides;
+   type T is new T1 with private;
+   overriding
+   procedure Foo;      -- partial view is overriding
 private
-   type T is new T2;
-   procedure Foo overrides;
+   type T is new T2 with ...;
+   overriding
+   procedure Foo;      -- unnecessary but harmless overriding clause
 end P;
+
+Implementing the checking of overriding takes some care, because an
+operation may become overriding at a later point (because of the rules of
+7.3.1(6)). A compiler always knows that such overriding will happen later,
+so this should not provide an implementation burden.
+
+An example of how this could happen:
+
+pragma Explicit_Overriding;
+
+package P is
+    type T is tagged private;
+private
+    type T is ...
+    procedure Op (Y : T);
+end P;
+
+package P.C is
+    type NT is new T with null record;
+    overriding
+    procedure Op (Y : NT);     -- OK.
+    package Nested is
+        type NNT is new T with null record;
+        procedure Op (Y : NNT); -- Illegal because the body of Nested has
+                                -- visibility on primitive 'Op'
+                                -- We must add "overriding"
+                                -- or "overriding or not".
+    end Nested;
+private
+    -- P.C.Op overrides P.Op here (P.Op is inherited here).
+end P.C;
+
+package body P.C is
+    package body Nested is
+        -- P.C.Nested.Op overrides P.Op here (P.Op is inherited here).
+    end Nested;
+end P.C;
+
+In this situation, the types NT and NNT are not private types and so there
+is no possibility of an overriding clause. Thus even though at the places
+where they are declared, the Op of T is not visible nevertheless the
+eventual overriding has to be mentioned. But we can write "overriding or not"
+as indicated in the comment to avoid breaking the abstraction (privateness)
+of the original type P.T.
+
+Contrast this with
+
+package P.C2 is
+    type NT is new T with private;
+    overriding
+    procedure Op (Y : NT); -- Illegal, this doesn't override anything.
+    package Nested is
+        type NNT is new T with private;
+        procedure Op (Y : NNT); -- OK.
+    private
+        type NNT is new T with null record;
+         -- Error: We need an overriding clause for Op here with
+         -- "overriding" or "overriding or not"
+    end Nested;
+private
+    type NT is new T with null record;
+    -- P.C.Op overrides P.Op here (P.Op is inherited here).
+    -- Thus, we need "overriding procedure Op (Y : NT);" here.
+end P.C2;
 
-This covers the situation where T1 does not have the operation Foo but T2 does.
+Here the types NT and NNT are private types and so overriding clauses
+are required.
 
+
 The configuration pragma Explicit_Overriding does not necessarily apply to the
 entire partition. It can be given in front of individual units in order to
 apply only to those units. This allows subsystems which take advantage of the
@@ -367,7 +565,7 @@
 much more attractive than if the words had to be reserved.
 
 An advantage over pragmas is that the syntax is clearly part of the
-declaration whereas pragmas are not. In the alternative approach the pragmas
+declaration whereas pragmas are not. In the pragma approach the pragmas
 had to immediately follow the declaration (with optional inclusion of the
 subprogram identifier) and required special rules for the pragmas to ensure
 that they only applied to the immediately preceding declaration. The normal
@@ -376,31 +574,25 @@
 also dangers if the pragmas get separated from the declaration during
 program amendment if the identifier is not included and including it seems
 a burden.
-
-We also considered "is overriding" rather than "overrides" but this led to
-the awkward
 
-   procedure Op(X: T) is overriding is abstract;
+We also considered various other forms of syntax where the indicator
+followed the details of the subprogram such as
 
-The double use of is was considered ugly.
-
-We also considered placing the overriding indicator at the beginning thus
-
-   overriding
-   procedure Op(X: T) is abstract;
+   procedure Op(X: T) overrides is abstract;
 
-and at the end
+   procedure Pop(Y: TT) overrides renames Pip;
 
-   procedure Pup is new Pap(P1 => A1, P2 => A2) maybe overrides;
+   procedure Pup overrides is new Pap(P1 => A1, P2 => A2);
 
-Placing the indicator at the beginning was felt to upset the layout.
-Placing the indicator at the end makes it a long way away from the
-designator to which it applies in the case of a generic instantiation
- - remember that the actual parameter list could be several pages long.
-
-The keyword "overrides" seems natural but "maybe overrides" is perhaps unusual
-and introduces the keyword "maybe". Other possibilities are "perhaps overrides",
-or even "perchance overrides".
+However, it proved difficult to resolve the different grammatical forms and
+the need to indicate optional overriding as well. Placing the indicator at
+the front has the merit of being uniform and easily seen by the reader.
+
+The keyword "overriding" seems natural but the somewhat whimsical reuse of
+existing reserved words in "overriding or not" is perhaps unusual. No better
+alternative has presented itself and the optional form will not be that
+frequent. Other possibilities which were rejected included "maybe overriding",
+"possibly overriding", "overriding optional", and "overriding unknown".
 
 !corrigendum 8.3(26)
 
@@ -411,7 +603,1060 @@
 
 At the Cupertino and Vienna meeting, John Barnes indicated that he would
 prefer this AI to use keywords. It was suggested that he prepare an alternative
-AI using keywords.
+AI using keywords. (John often wishes that he had kept his mouth shut.)
+
+*************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, Marh 5, 2003  3:55 PM
+
+I notice in the minutes that in cases where you
+have to give the overriding clause in the private
+part for an operation declared in the visible part,
+we run into trouble with defining full conformance
+if the overriding declaration involves an instantiation.
+It seems easy enough to outlaw that, since we outlaw
+it in cases where we allow renaming-as-body, which has
+similar conformance problems.
+
+Why not just require that the instantiation have
+a new name, and then use an overriding, renaming-as-body
+to hook it up to the visibly declared operation?
+
+In Ada 95 we didn't allow instantiations to "complete"
+a subprogram declaration both because of the tricky
+conformance issues, and because of the possible confusion
+in trying to match up an instantiation with a separate
+declaration, since the instantiation doesn't have any
+explicit parameter profile.  Hence, it would seem just
+as reasonable to disallow using instantiations with an
+"overriding" prefix under the same circumstances.
+
+*************************************************************
+
+Editor's note: The following originally was a private discussion between
+John Barnes, Pascal Leroy, and me (Randy Brukardt) about a draft of version
+4 of this AI. We started discussing a number of deep issues about this
+AI, and eventually decided that the discussion should be recorded for
+posterity. I've edited out private chit-chat and irrelevancies. And I've kept
+the threads together,  which is not necessarily the order that items actually
+were discussed. The discussion took place between April 22 and April 26 2003.
+
+---- 1st thread
+---- Randy Brukardt
+
+John asked
+
+> The minutes of the last meeting say "Besides, if the syntax
+> is given, it is always checked. The configuration pragma
+> only changes the checking that occurs when the syntax is not
+> used."
+>
+> Did we really agree this?
+
+Yes.
+
+> I thought that the pragma had to
+> be on for the checking to be invoked. That is how the AI
+> currently reads. But, clearly we need to permit the syntax
+> always and so I suppose we had better check it because it
+> would be confusing not to.
+
+Exactly. It would be very strange if "overriding procedure" didn't have to
+override something. If the AI doesn't currently say that, its wrong. (Gee, that
+was easy. :-)
+
+> And then
+>
+> 2
+>
+> Are we going to permit the "optional overriding" indicator
+> everywhere or only in those places where it is necessary (in
+> generic specs)?  Currently it is permitted everywhere and
+> just effectively switches the checking off. But is this
+> useful?  Note that "optional overriding" is not the
+> syntactic form I intend to propose. I will keep that secret
+> for a moment. Note that the summary of the minutes say
+> "Don't require maybe overriding on partial view". Maybe they
+> should have said "Don't permit maybe overriding on partial
+> view".
+
+I don't think that was the intent. Trying to figure out where something should
+be (or should not be) allowed seems like a fools game to me. People hate the
+places where Ada does that (in out parameters on functions are the prime
+example), and I don't think we ought to add more of them absent very good
+reasons.
+
+My model of these indicators on the partial view is that they ought to reflect
+the reality of the partial view. That is, if "overriding" is given, it better
+be a visibly overriding routine. But that may be too much checking and/or too
+hard to define, and certainly it is not needed.
+
+In any case, prohibiting "optional overriding" on a partial view wouldn't make
+sense (what if that partial view is in a generic spec?? Do you really insist to
+repeat the indicator in the private part, even though it just says 'don't
+check'??).
+
+In any case, one model of the absence of the configuration pragma is simply
+that all subprograms without an indicator have an implicit "optional
+overriding". Which only makes sense if you allow it everywhere.
+
+---- Pascal Leroy
+
+I don't quite understand Randy's replies to these questions.  It seems
+to me that "optional overriding" should only be allowed in generic
+specs, and that it should not be allowed on partial views.  That seems
+to be the essence of the discussion as reflected in the minutes and as I
+remember it.
+
+---- Randy Brukardt
+
+No, the minutes say "don't REQUIRE "maybe overriding" on the partial view".
+That's because John's previous version did require that on the partial view if
+you didn't want to break privateness.
+
+I don't think we discussed the notion of restricting "optional overriding" at
+the meeting; certainly *I* wasn't discussing that! I was only discussing the
+notion of requiring its use in a partial view where you would give the real
+overriding or not in the private part.
+
+I see no reason to restrict the use of modifier; that seems like a
+methodological restriction best left to style guides, not the language. Where
+such things were done in Ada, we've had continuing controversy (see: function
+parameter modes, 'in out'). Let's not go there again.
+
+But that's my opinion; I'm certain we've never discussed this topic at the ARG
+level (and perhaps we should).
+
+---- Pascal Leroy
+
+I disagree here, but surely this should be discussed during a meeting,
+not between the three of us.
+
+Adding "overriding or not" outside a generic has no possible usefulness,
+except that of working around the constraints imposed by pragma
+Explicit_Overriding.  As a programmer, you are always able to decide if
+a declaration is an override or not.  The only case where you would want
+to use "overriding or not" is if you are too lazy to determine if a
+declaration is an override or not.  I don't think we want to add
+language support for laziness.
+
+---- End 1st thread.
+---- 2nd thread:
+---- John Barnes
+
+I ... found this suggestion from Tucker to get around the
+conformance with instantiation problem.
+
+Good idea?
+
+[Editor's note: This is Tucker's mail of March 5, 2003, appended above.]
+
+---- Randy Brukardt
+
+It seems reasonable to me. I don't know if people would complain, but it at
+least avoids the hand-waving in the wording.
+
+---- Pascal Leroy
+
+This certainly has the advantage that you don't have to invent complicated
+wording to define full conformance with instantiations.
+
+On the other hand, it would make it harder to change existing code to take
+advantage of AI 218, as you would have to introduce extra renamings.
+
+I am not sure how often the overrider is an instantiation; although this is
+certainly going to depend on the programming style, I suppose that this is
+going to be rather infrequent in practice.
+
+Even if we ignore for a moment the complexity of the RM wording for defining
+full conformance with an instantiation, I have a hunch that the rules are
+going to be sufficiently convoluted that they would lead to obscure errors
+and user puzzlement (of course, I would need to see the rules to be sure,
+but remember that full conformance in Ada 83 did puzzle many users because
+of unnecessarily stringent requirements).
+
+So I guess I am saying that I am slightly in favor of following Tuck's
+suggestion.  However, in order to make an informed choice, I would like to
+see at least a first-order approximation of the rules for full conformance
+with an instantiation (maybe my gut feeling is wrong and they are not that
+complicated after all).
+
+---- John Barnes
+
+Of course the other irritating thing with this conformance
+business is that overriding of tagged types requires type
+conformance whereas that for untagged types only requires
+subtype conformance.
+
+But I think we should use full conformance because it will
+look very odd if the overriding clause uses different names
+for the parameters.
+
+---- End 2nd thread.
+---- 3rd thread:
+---- John Barnes
+
+Here is a tentative attempt at a rewrite of 218.
+
+---- Randy Brukardt
+
+OK, here goes.
+
+The last paragraph of the !proposal seems awkward, although I think it has the
+right meaning. Perhaps "even in the absence of the pragma Explicit_Overriding"
+should be put into parens ("always made" certainly includes this) - certainly
+it reads a lot better without the "even in..." phrase (but I think its
+necessary, since its the point).
+
+8.3(23.1) first sentence says:
+
+  If an explicit declaration of a visible operation of a private type by
+  a subprogram_declaration, abstract_subprogram_declaration, subprogram_
+  renaming_declaration or generic_instantiation includes an overriding_
+  indicator then it is permitted to give an overriding_clause for
+  the operation in the corresponding private part.
+
+Shouldn't this say "does not include" instead of "includes"? I don't see any
+point to having:
+   overriding or not procedure foobar...
+ private
+   overriding procedure foobar...
+
+8.3(26) first question:
+
+Legality rules only apply in the visible specification of a generic instance
+unless the language says otherwise. Here, we clearly want these checks to occur
+in the private part as well (it makes no sense to ignore overridding indicators
+in generic instantiations). This check is not made in a generic instance body,
+so that generic sharing is still possible and that the contract is at least
+solely in the generic specification. (Overriding in bodies is rare, anyway).
+And the wording is correct.
+
+!discussion, first question.
+
+I'm pretty sure that we don't want to bother with the syntax on bodies for an
+obscure case. Indeed, people probably would prefer an error in that case,
+because it's unlikely that they actually meant to override anything. I'm not
+certain that I believe the explanation (you'll probably tell me that I wrote it
+originally); I'd probably just say that the value of supporting this new syntax
+on bodies is minimal (since you can always give an appropriate specification),
+and it is more likely that any overriding in a body is accidental rather than
+intentional. And I can't comment on buggering your book. :-)
+
+The 'later overridding' discussion.
+
+I'm not sure that the current wording (8.3(26.1) and 8.3(26.6)) has this
+effect. It's not clear when "an overriding declaration for the full view of the
+type" is determined. We want "overriding anywhere" informally, but the ARG has
+not liked such wording in the past. Secondly, the first sentence says "shall
+not be an overriding declaration for the view of the type at that place." That
+rule applies to types without partial views; but really we want that to apply
+only for partial views; for other types we want to use the second part of the
+rule (the one about full views).
+
+I don't think we have a choice but to use this interpretation for full types.
+Otherwise, the visibility gets very messy, and you'd have to allow additional
+overridding clauses anywhere.
+
+OTOH, the fact that the check is different (using a partial place rather than
+anywhere) for partial views is uncomfortable. (BTW: T is tagged, so NT and NNT
+need "with null record"). If we had P.C2:
+
+package P.C2 is
+    type NT is new T with private;
+    overriding
+    procedure Op (Y : NT);     -- Illegal, this doesn't override anything.
+    package Nested is
+        type NNT is new T with private;
+        procedure Op (Y : NNT); -- OK.
+    private
+        type NNT is new T with null record;
+        -- Error: We need "overridding" or "overridding or not" procedure Op here.
+	  -- That's because the body of Nested has visibility on primitive 'Op'
+    end Nested;
+private
+    type NT is new T with null record;
+    -- P.C.Op overrides P.Op here (P.Op is inherited here).
+    -- Thus, we need "overriding procedure Op (Y : NT);" here.
+end P.C2;
+
+I'm not expecting Mr. Private to be happy with this, but he'll need a better
+idea (and wording for it!) in order to change it. And this is a lot more
+important than adding restrictions to "overrides or not".
+
+Generic paragraph question:
+
+Yes. :-)
+
+It is OK.
+
+Second generic question:
+
+Yup. I always preferred allowing the contract to be modified in this way. It
+seems to be a useful capability. Moreover, if we allowed that, arguably, we
+wouldn't need "overriding or not". (I don't think it makes sense for a generic
+to be bisexual: both allowing and not allowing overriding. Generally, you do
+not want overriding in a generic, certainly not for mix-in uses.)
+
+?? I concluded that if the partial view said "overriding" then it would be a
+burden to require it in the full view as well.
+
+Yes, and useless noise to boot. Why be required to repeat something obvious??
+
+?? One might argue that if the
+partial view said "overriding or not" then the full view need not be checked??
+
+Yes, I expect that to be the semantics. Of course, Pascal doesn't want to allow
+it in that case, which also would answer the question.
+
+The generic mixin case should that we indeed have to allow "overriding or not"
+on a partial view. The good news is that the example is bogus, for two reasons:
+"overridding or not" on the partial view should extent to the private part, so
+no overridding clause is required (but its allowed). More importantly, where is
+PDGT coming from?? There is no such type in the spec. of the generic, and any
+outside type wouldn't match the generic formal. You can't construct such an
+example with formal private types. We could try:
+    type GT is new T with private;
+    type PDGT is new T with private;
+but I don't know if the derived declaration is legal. If the check is
+assume-the-worst, it fails; if it is assume-the-best, it is allowed. The
+wording of the language suggests that it is a hole - 7.3(8) is a legality rule
+that applies only in the visible part of an instance (that's the default). The
+second sentence seems to need to apply to the entire rule, not just "the
+requirement that the type is specific".
+
+---- Pascal Leroy
+
+Good job, John, but I think there are a number of nasty issues that
+remain to be considered (that's the problem when proposals become more
+precise, you can write examples and ask "what if" questions).
+
+My comments interspersed below.
+
+Pascal
+--
+
+> In 2.9(3) as modified by AI 284 add the following to the list of
+> nonreserved keywords
+>
+>       overriding
+>
+> Change the syntax in 6.1 to read
+> overriding_indicator ::= overriding [or not]
+> subprogram_declaration ::=
+>                [overriding_indicator] subprogram_specification ;
+> abstract_subprogram_declaration ::=
+>    [overriding_indicator] subprogram_specification is abstract;
+> overriding_clause ::= overriding_indicator subprogram_specification ;
+
+I like the syntax.  In fact, this is the first time that I see a syntax
+that I like for the "optional" case.  Although it has a Norm Cohen
+flavor, it reads well, especially considering that it's on a line of its
+own.
+
+> Its profile shall be
+> fully conformant with the profile of the subprogram_declaration,
+> abstract_subprogram_declaration or subprogram_renaming_declaration
+> or the profile implied by the generic_instantiation.
+
+Intense hand-waving in the last part of this sentence.  I think you'll
+need more words than that.  The problem is that you are requiring full
+conformance (which is approximately lexical matching) but the generic
+instantiation model in 12.3(13-14) kills you.  Consider:
+
+    generic
+        type T is private;
+    procedure P (X : T);
+
+    procedure I is new P (Integer);
+
+According to 12.3(13) the profile of the instance is:
+
+    procedure I (X : T)
+
+and 12.3(14) explains that in this context the name T denotes the
+subtype Integer.  There is no way that the user can write a subprogram
+specification that is fully conformant with this profile.  (It's really
+a technicality, in the sense that there is no doubt what the right
+answer is here, but writing the words is going to be challenging.)
+
+> In addition to the places where  Legality Rules
+> normally apply, these rule also applies in the private part of an
+> instance of a generic unit.
+>
+> ?? What's that last bit for Randy?  Is it still OK???
+
+I don't think it's for Randy.  I believe it only says that all this
+overriding checking happens in the private part as well as the visible
+part.  It would be silly if we made visible parts "safe" and private
+parts "unsafe".  (Or am I missing something?)
+
+This leads me to wonder what happens in a generic body if you derive
+from a formal type.  Surely we don't want the legality of the
+instantiation to depend on the contents of the body.  It seems that the
+AI ought to say a few well-chosen words about this (I suppose we need
+some form of assume-the-worst rule).
+
+> package P.C is
+>     type NT is new T;
+>     overriding
+>     procedure Op (Y : NT);     -- OK.
+>     package Nested is
+>         type NNT is new T;
+>         procedure Op (Y : NNT); -- Illegal because the body of Nested has
+>                                 -- visibility on primitive 'Op'
+>                                 -- We must add "overriding"
+>                                 -- or "overriding or not".
+>     end Nested;
+> private
+>     -- P.C.Op overrides P.Op here (P.Op is inherited here).
+> end P.C;
+>
+> package body P.C is
+>     package body Nested is
+>         -- P.C.Nested.Op overrides P.Op here (P.Op is inherited here).
+>     end Nested;
+> end P.C;
+>
+> Note the possibility of using "overriding or not" in this example as
+> indicated in the comment; it can be used here to avoid breaking the
+> abstraction (privateness) of the original type P.T.
+>
+> ?? Is Mr Private happy with this??
+
+Mr Privacy is confused.  My understanding is that you never have to add
+"overriding or not" to a declaration (except in generics).  In this case
+I would expect P.C.Nested.Op to have no overriding_indicator, and the
+body to contain an overriding_clause.  That would reflect the fact that
+Op doesn't override at the point of its declaration, and it wouldn't
+break the privacy of P.T.
+
+Hmm, but we don't allow an overriding_clause in a body, because it must
+occur before the freezing point.  Why this rule about freezing?
+
+Note that, contrary to what the comment seems to imply, adding
+"overriding" to Op would break the privacy of P.T.
+
+I guess this example needs more thought.
+
+> ??  And so it seems that the earlier remarks that we didn't want to modify
+> the contract rules are not right. We can modify the contract to prevent
+> overriding but not to require it. Tis an odd business chaps ??
+
+That seems quite broken.  It appears to violate the Great Cosmic Duality
+between generics and (normal) private types.  Consider your example:
+
+package P is
+   type T is private;
+   function "+" (Left, Right: T) return T; -- don't know here
+private
+   type T is range 0 .. 100;
+   overriding
+   function "+" (Left, Right: T) return T;  -- now we know
+end P;
+
+As the comment correctly points out, the absence of an
+overriding_indicator on the partial view really means "heck I don't know
+for sure, but so far it doesn't override" and the overriding_clause then
+tells the truth when we know it.  Now look at the generic equivalent:
+
+generic
+    type T is private;
+package G is
+    type NT is new T;
+    function "+" (Left, Right : T) return T;
+end G;
+
+It would seem to me that the natural application of the Great Cosmic
+Duality would be to say that the absence of an overriding_indicator on
+G."+" really means "don't know" and that the instantiation ought to say
+the truth by using overriding_clauses:
+
+type T is range 0..100;
+
+package I is new G(T) with
+    overriding
+    function "+" (Left, Right : T) return T;
+end I; -- John to find a good syntax
+
+And, oh, we wouldn't need "overriding or not" anymore because the
+instantiation is the one who would say the truth.
+
+(Sorry for the "stream of consciousness" style here.  I am just
+inventing language as I type.  The proposed solution may be totally
+bogus, but I think the examples in the AI indicate a deep problem.)
+
+---- Randy Brukardt:
+
+Pascal said:
+
+> This leads me to wonder what happens in a generic body if you derive
+> from a formal type.  Surely we don't want the legality of the
+> instantiation to depend on the contents of the body.  It seems that the
+> AI ought to say a few well-chosen words about this (I suppose we need
+> some form of assume-the-worst rule).
+
+I don't believe that we can do assume-the-worst on this rule, since it is an
+either-or rule. If we did, we'd reject virtually all generic bodies containing
+a derivation (any instantiation MIGHT have an overridding routine) - the only
+ones that could work would be those for which all primitive routines have an
+overridding indicator (usually "overriding or not").
+
+Since the most important part of the rule is checked in the generic body anyway
+(that intentional "overridding" really is), the only check that would not get
+made in a generic instance body is the "accidential overridding" one. That
+doesn't seem too bad, especially as derivations in bodies are rare.
+
+An AARM note about this probably would be worth having. (Indeed, a lot of the
+!discussion probably ought to be in the AARM.)
+
+
+> > package P.C is
+> >     type NT is new T;
+> >     overriding
+> >     procedure Op (Y : NT);     -- OK.
+> >     package Nested is
+> >         type NNT is new T;
+> >         procedure Op (Y : NNT); -- Illegal because the body of Nested
+> >                                 -- has visibility on primitive 'Op'
+> >                                 -- We must add "overriding"
+> >                                 -- or "overriding or not".
+> >     end Nested;
+> > private
+> >     -- P.C.Op overrides P.Op here (P.Op is inherited here).
+> > end P.C;
+> >
+> > package body P.C is
+> >     package body Nested is
+> >         -- P.C.Nested.Op overrides P.Op here (P.Op is inherited here).
+> >     end Nested;
+> > end P.C;
+> >
+> > Note the possibility of using "overriding or not" in this example as
+> > indicated in the comment; it can be used here to avoid breaking the
+> > abstraction (privateness) of the original type P.T.
+> >
+> > ?? Is Mr Private happy with this??
+>
+> Mr Privacy is confused.  My understanding is that you never have to add
+> "overriding or not" to a declaration (except in generics).
+
+You never HAVE to; I think this example shows why you should be allowed to.
+
+> In this case
+> I would expect P.C.Nested.Op to have no overriding_indicator, and the
+> body to contain an overriding_clause.  That would reflect the fact that
+> Op doesn't override at the point of its declaration, and it wouldn't
+> break the privacy of P.T.
+>
+> Hmm, but we don't allow an overriding_clause in a body, because it must
+> occur before the freezing point.  Why this rule about freezing?
+
+So that there is a clear point at which the checking can be done. We need to
+know when the compiler has to go back and check all of the partial view
+subprograms that don't have overridding_clauses or an overriding_indicator. If
+you allowed overriding_clauses to happen in the body, you'd have to defer that
+check until you completed the compilation of the body. Which can be days or
+months later. I don't think we want an error in the spec. of a routine to
+fester until someone happens to compile a body. And then you'd have to somehow
+figure out when there was no body in order to do the check at the end of the
+spec.
+
+> Note that, contrary to what the comment seems to imply, adding
+> "overriding" to Op would break the privacy of P.T.
+>
+> I guess this example needs more thought.
+
+Yes; the compiler always knows that the routine is overriding, but supposedly
+the programmer does not. I think that this example really shows why you have to
+have "overridding or not" everywhere, because it is the only way to avoid
+breaking privacy in some cases.
+
+Note, however, that this is a dubious design. Usually, if you are intentionally
+overridding the routine, you would want to continue to do so in the private
+part (the routine ought to stay private). And most types ought to be private
+anyway; note that my similar example (which uses private types) has no problems
+with breaking privateness for NT.
+
+If you accidentially are overridding the private routine, that is exactly the
+case where trouble can happen and exactly what we're trying to detect. You
+really do need to break privateness enough to realize that "Op" is a bad name
+for this operation if you aren't intending to override the private. So I have
+to think that breaking privateness is inherent in the check. (Which is too
+bad.)
+
+> > ??  And so it seems that the earlier remarks that we didn't want to modify
+> > the contract rules are not right. We can modify the contract to prevent
+> > overriding but not to require it. Tis an odd business chaps ??
+>
+> That seems quite broken.  It appears to violate the Great Cosmic Duality
+> between generics and (normal) private types.  Consider your example:
+
+That duality really doesn't exist in Ada 95 as it is (the sharing enabling
+rules among others see to that), and if we adopt "limited with", it will be
+completely dead (since "limited with" doesn't work at all with instantiations,
+meaning that it is useless if some of the types are declared in generics). So I
+think trying to preserve it here is questionable at best.
+
+Your two examples don't even look similar; I have a hard time believing anyone
+will be confused.
+
+> It would seem to me that the natural application of the Great Cosmic
+> Duality would be to say that the absence of an overriding_indicator on
+> G."+" really means "don't know" and that the instantiation ought to say
+> the truth by using overriding_clauses:
+>
+> type T is range 0..100;
+>
+> package I is new G(T) with
+>     overriding
+>     function "+" (Left, Right : T) return T;
+> end I; -- John to find a good syntax
+>
+> And, oh, we wouldn't need "overriding or not" anymore because the
+> instantiation is the one who would say the truth.
+
+If you want to kill this idea, this is a wonderful way to do it. The last time
+I was working on 218, I pretty much concluded it was intractable and that the
+idea had to be abandoned.
+
+John managed to rescue it with "overridding_clause"s, and we now seem to be
+near a solution. But if we start adding this to instantiations, the complexity
+factor has gone far beyond the benefits.
+
+I'm wondering personally if the idea of catching "accidential overriding" is
+worth the effort. If we stopped trying to do that (and left "no indicator" as
+"don't care"), it seems like most of these privateness problems (and the
+weirdness of the partial view rules) would go away.
+
+Come to think of it, why are we using a configuration pragma anymore? Once we
+have syntax, we can made the default to be "don't care" (that is, Ada 95
+rules). Perhaps if we explicitly indicate the other cases:
+
+     not overriding
+     procedure Foobar (Pascal, John : ...);
+
+It's mildly annoying to have to write more to be safe, but then again that's
+what Ada's about. Then we don't have to try to describe where checking is done
+(it better be true at the point of the declaration of the overriding
+indicator); we don't have to describe where the pragma applies; and we probably
+could even allow overriding_clauses after freezing (because there is no
+rechecking - all checks occur at the point of the declaration/overriding_clause
+in question).
+
+One could imagine a tool or mode that tried to insure that all subprograms
+ultimately had an overriding_indicator or overriding_clause, but we could leave
+that for the style people and avoid having to worry about breaking privateness
+ourselves (if someone wants to break privateness to enforce a style, that's not
+our problem).
+
+Perhaps that should be an alternative #3??? (We need alternative #2 to prove
+why having the default be safe gets us into trouble.
+
+---- Pascal Leroy
+
+> Since the most important part of the rule is checked in the
+> generic body anyway (that intentional "overridding" really
+> is), the only check that would not get made in a generic
+> instance body is the "accidential overridding" one. That
+> doesn't seem too bad, especially as derivations in bodies are rare.
+>
+> An AARM note about this probably would be worth having.
+> (Indeed, a lot of the !discussion probably ought to be in the AARM.)
+
+I'm not sure if we are discussing the same thing.  The thing that bothers me
+is that, in John's current write-up, the overriding_indicator (or more
+precisely, the absence thereof) changes the contract.  Consider the
+following (note that this is the untagged case, as I believe that in the
+tagged case 3.9.1(4) saves us):
+
+    generic
+        type GT is new T;
+    package Gen is
+        ...
+    end Gen;
+
+    package body Gen is
+        type DGT is new GT;
+        procedure Op (Z : DGT);
+    end Gen;
+
+As I read the AI, it would seem that an instantiation of Gen is illegal if
+the actual type has an Op.  At this point Mr. Shared Generic should have a
+heart attack.
+
+One way out of this conundrum is to say that in generic bodies, primitive
+operations of types that are derived from a formal type fall in the "don't
+know" category.  Whether this has to be stated explicitly by writing
+"overriding or not" or whether this is the default (and "overriding" is
+illegal) is another issue.  (Note that this would argue in favor of having
+"don't know" be the default, something you propose later on.)
+
+> > Mr Privacy is confused.  My understanding is that you never have to
+> > add "overriding or not" to a declaration (except in generics).
+
+Well, the comment "We must add 'overriding' or 'overriding or not'" seems to
+imply the contrary.  I believe that this comment is wrong anyway.
+
+> > Hmm, but we don't allow an overriding_clause in a body, because it
+> > must occur before the freezing point.  Why this rule about freezing?
+>
+> So that there is a clear point at which the checking can be
+> done. We need to know when the compiler has to go back and
+> check all of the partial view subprograms that don't have
+> overridding_clauses or an overriding_indicator. If you
+> allowed overriding_clauses to happen in the body, you'd have
+> to defer that check until you completed the compilation of
+> the body. Which can be days or months later.
+
+Note that we have at least one case where this happens today, viz. the case
+of an incomplete type completed in the body, where you use 'Class in the
+spec.  OK, this is particularly elegant language design, but at least that's
+a precedent ;-)
+
+My model is that the user writes on the declaration an overriding_indicator
+which reflects the situation at this place.  If the situation later changes,
+he has to add an overriding_clause.  If that's months later, fine, but at
+least it will be a conscious decision to override or not.  The places where
+implicit declarations occur (and therefore where overriding occur) are very
+precisely defined by the RM, and these are the places where
+overriding_indicators/_clauses should occur.
+
+Let me come back to my generic example again:
+
+    generic
+        type T is private;
+    package G is
+        type NT is new T;
+        function "+" (Left, Right : T) return T;
+    end G;
+
+In the generic, "+" doesn't override anything.  I am inclined to think that
+there is no point in saying "overriding or not", since there is no "+" in
+sight, and the situation is perfectly clear.  Compare this with the case
+where T is a formal integer type, and where evidently "overriding" would be
+required.
+
+In the case of the formal private type, "+" may become overriding on the
+instantiation:
+
+    type T is range 0..100;
+    package I is new G(T);
+
+Here we have two options:
+
+1 - Provide some syntax to specify that I."+" is overriding.  This is the
+"safe" solution, as it makes possible to control overriding even in
+generics, but at the cost of possibly heavyweight syntax.
+
+2 - Ignore the issue and say that it's OK for a declaration that was not
+overriding in the generic to become overriding in the instance.  From the
+perspective of the instance, it is exactly as if you had "overriding or
+not".  But from the perspective of the generic this is a bit safer as you
+have a way to express that "+" is not overriding (so if the formal part is
+later changed and T gets a primitive "+", you will be informed that there is
+potentially a problem).
+
+Am I saying that we don't need "overriding or not" after all?
+
+> If you want to kill this idea, this is a wonderful way to do
+> it. The last time I was working on 218, I pretty much
+> concluded it was intractable and that the idea had to be abandoned.
+>
+> John managed to rescue it with "overridding_clause"s, and we
+> now seem to be near a solution. But if we start adding this
+> to instantiations, the complexity factor has gone far beyond
+> the benefits.
+
+I don't think "kill" is a very productive word here.  I was trying to look
+at the implications of the model, which is currently not satisfactory for
+generics.
+
+I am actually much more optimistic about this AI than I ever was.  First, we
+have good syntax for the first time.  Syntax is not nearly as important as
+semantics of course, but it's the first thing that people see, so it can be
+a stumbling block.  Second, we have (with the overriding_clause) a good
+solution to deal with overriding occurring at diverse places in the program
+text.  There are still issues to be resolved, notably for generics, but we
+are certainly starting to have a much deeper understanding of these issues.
+
+(Remember, this is an AI that was approved by WG9 two years ago, and we were
+entirely clueless about the problem then.)
+
+> Come to think of it, why are we using a configuration pragma
+> anymore? Once we have syntax, we can made the default to be
+> "don't care" (that is, Ada 95 rules). Perhaps if we
+> explicitly indicate the other cases:
+>
+>      not overriding
+>      procedure Foobar (Pascal, John : ...);
+
+I don't think changing the default simplifies the definitional problems with
+generics, private types, overriding occurring in odd places, etc.  It just
+means that you have to write different combinations of keywords to achieve
+the same effect.
+
+This being said, this is an attractive idea.  The pragma Explicit_Overriding
+always gave me bellyaches, so I'd be happy to get rid of it.
+
+For people who want to be safe and are not excited about writing their own
+ASIS tool, we could actually provide restrictions to control what checks
+ought to be performed:
+
+    pragma Restrictions (No_Implicit_Overriding);
+    pragma Restrictions (No_Implicit_Overloading);
+
+No_Implicit_Overriding would require that you write "overriding" when you
+override a subprogram.  No_Implicit_Overloading would required that you
+write "not overriding" when you declare a new overload.  Using the two
+restrictions together would require that you write either "overriding" or
+"not overriding" before each declaration.  (And maybe "overriding or not" if
+we have to keep this one for generics.)
+
+> It's mildly annoying to have to write more to be safe, but
+> then again that's what Ada's about.
+
+That doesn't bother me as it would be easy to write a tool to add the
+overriding_indicators as appropriate (I could write such a tool in a couple
+of days).  One could argue that all these overriding_indicators would
+degrade readability, but with the restrictions you could choose the
+trade-off between readability and safety.
+
+---- Randy Brukardt:
+
+> > Since the most important part of the rule is checked in the
+> > generic body anyway (that intentional "overridding" really
+> > is), the only check that would not get made in a generic
+> > instance body is the "accidential overridding" one. That
+> > doesn't seem too bad, especially as derivations in bodies are rare.
+> >
+> > An AARM note about this probably would be worth having.
+> > (Indeed, a lot of the !discussion probably ought to be in the AARM.)
+>
+> I'm not sure if we are discussing the same thing.  The thing
+> that bothers me
+> is that, in John's current write-up, the overriding_indicator (or more
+> precisely, the absence thereof) changes the contract.  Consider the
+> following (note that this is the untagged case, as I believe
+> that in the
+> tagged case 3.9.1(4) saves us):
+>
+>     generic
+>         type GT is new T;
+>     package Gen is
+>         ...
+>     end Gen;
+>
+>     package body Gen is
+>         type DGT is new GT;
+>         procedure Op (Z : DGT);
+>     end Gen;
+>
+> As I read the AI, it would seem that an instantiation of Gen
+> is illegal if
+> the actual type has an Op.  At this point Mr. Shared Generic
+> should have a
+> heart attack.
+
+No, you're forgetting 12.3(11): legality rules aren't checked in an instance
+body. So there is no check, and the instantiation is legal. That IS what I was
+talking about. It's annoying to not have that check, but it follows
+automatically from the existing Ada rules. We probably ought to have a note,
+though, and your confusion shows why.
+
+> > > Hmm, but we don't allow an overriding_clause in a body, because it
+> > > must occur before the freezing point.  Why this rule about freezing?
+> >
+> > So that there is a clear point at which the checking can be
+> > done. We need to know when the compiler has to go back and
+> > check all of the partial view subprograms that don't have
+> > overridding_clauses or an overriding_indicator. If you
+> > allowed overriding_clauses to happen in the body, you'd have
+> > to defer that check until you completed the compilation of
+> > the body. Which can be days or months later.
+>
+> Note that we have at least one case where this happens today, viz. the case
+> of an incomplete type completed in the body, where you use 'Class in the
+> spec.  OK, this is particularly elegant language design, but at least that's
+> a precedent ;-)
+
+One that we're planning to make Obsolecent, simply because its such a bad
+design. Please, let's not make that mistake again...
+
+> My model is that the user writes on the declaration an overriding_indicator
+> which reflects the situation at this place.  If the situation later changes,
+> he has to add an overriding_clause.  If that's months later, fine, but at
+> least it will be a conscious decision to override or not.  The places where
+> implicit declarations occur (and therefore where overriding occur) are very
+> precisely defined by the RM, and these are the places where
+> overriding_indicators/_clauses should occur.
+
+That's a fine model, but it will cause significant extra implementation effort.
+That's because the visibility of these things is a separate set of magic from
+determining whether they override or not (which uses visibility only to
+determine if it will never override - in large part because there is no visible
+semantic difference between overriding early or late - only between not
+overriding at all and overriding). That means any check such as you envision
+has to take into account a lot of visibility information which is unrelated to
+the overrides or not decision.
+
+And I'm convinced if you want to use that model, you have to use an explicit
+"not overriding" tag.
+
+> Let me come back to my generic example again:
+>
+>     generic
+>         type T is private;
+>     package G is
+>         type NT is new T;
+>         function "+" (Left, Right : T) return T;
+>     end G;
+>
+> In the generic, "+" doesn't override anything.  I am inclined to think that
+> there is no point in saying "overriding or not", since there is no "+" in
+> sight, and the situation is perfectly clear.  Compare this with the case
+> where T is a formal integer type, and where evidently "overriding" would be
+> required.
+>
+> In the case of the formal private type, "+" may become overriding on the
+> instantiation:
+>
+>     type T is range 0..100;
+>     package I is new G(T);
+>
+> Here we have two options:
+>
+> 1 - Provide some syntax to specify that I."+" is overriding.  This is the
+> "safe" solution, as it makes possible to control overriding even in
+> generics, but at the cost of possibly heavyweight syntax.
+>
+> 2 - Ignore the issue and say that it's OK for a declaration that was not
+> overriding in the generic to become overriding in the instance.  From the
+> perspective of the instance, it is exactly as if you had "overriding or
+> not".  But from the perspective of the generic this is a bit safer as you
+> have a way to express that "+" is not overriding (so if the formal part is
+> later changed and T gets a primitive "+", you will be informed that there is
+> potentially a problem).
+>
+> Am I saying that we don't need "overriding or not" after all?
+
+Yes. 2 is essentially saying that the rules are not enforced in an instance at
+all. I don't view that as very safe.
+
+But I do not like either of these solutions. I'm in favor of solution 3 (at
+least for generic specs):
+3 - Overriding indicators are part of the "contract". Thus, this instantiation
+is illegal - the rechecking of the instance spec fails.
+
+Note that my original proposal did NOT check these indicators (they were
+pragmas then) in the generic specification. The idea was that they WERE a first
+class part of the contract. Argubly, they should be up top with the formal
+types, but that seems way too heavy.
+
+> > If you want to kill this idea, this is a wonderful way to do
+> > it. The last time I was working on 218, I pretty much
+> > concluded it was intractable and that the idea had to be abandoned.
+> >
+> > John managed to rescue it with "overridding_clause"s, and we
+> > now seem to be near a solution. But if we start adding this
+> > to instantiations, the complexity factor has gone far beyond
+> > the benefits.
+>
+> I don't think "kill" is a very productive word here.  I was trying to look
+> at the implications of the model, which is currently not satisfactory for
+> generics.
+
+I think it's fine, and your alternatives are worse (and I expect that my
+alternative will get little support as well).
+
+> I am actually much more optimistic about this AI than I ever was.  First, we
+> have good syntax for the first time.  Syntax is not nearly as important as
+> semantics of course, but it's the first thing that people see, so it can be
+> a stumbling block.  Second, we have (with the overriding_clause) a good
+> solution to deal with overriding occurring at diverse places in the program
+> text.  There are still issues to be resolved, notably for generics, but we
+> are certainly starting to have a much deeper understanding of these issues.
+>
+> (Remember, this is an AI that was approved by WG9 two years ago, and we were
+> entirely clueless about the problem then.)
+
+Agreed with that. One reason I never implemented it was that I couldn't figure
+out how to decide when a subprogram was "not overridden", because there was no
+"point" at which to check. I should have realized that that meant that there
+was a significant problem in the model.
+
+> > Come to think of it, why are we using a configuration pragma
+> > anymore? Once we have syntax, we can made the default to be
+> > "don't care" (that is, Ada 95 rules). Perhaps if we
+> > explicitly indicate the other cases:
+> >
+> >      not overriding
+> >      procedure Foobar (Pascal, John : ...);
+>
+> I don't think changing the default simplifies the definitional problems with
+> generics, private types, overriding occurring in odd places, etc.  It just
+> means that you have to write different combinations of eywords to achieve
+> the same effect.
+
+Actually, it does, because it means that we can say that the check always
+occurs at the point of the overriding indicator. We can't do that now, because
+the absence of an indicator means that a check is done "sometime" that there is
+no overriding. All of your concerns with the placement of overriding_clauses
+stem from that, and all of that can be eliminated - along with the freezing
+requirement. (Although I guess with the existing model that you would prefer
+that the freezing requirement be eliminated and that all of the checks be
+repeated anytime that the visibility changes, which I think is silly.)
+
+Also, the "implicit" generic contract isn't quite so bad, because it is always
+spelled out with an overriding indicator. Admittedly, its still buried, but
+that is true of anything that causes an error in the
+assume-the-best-and-recheck-the-instance model -- such as deriving from a
+library-level tagged type and having to instantiate at library level. That's an
+"implied contract", and it is a far less explicit contract than this one would
+be.
+
+> This being said, this is an attractive idea.  The pragma Explicit_Overriding
+> always gave me bellyaches, so I'd be happy to get rid of it.
+>
+> For people who want to be safe and are not excited about writing their own
+> ASIS tool, we could actually provide restrictions to control what checks
+> ought to be performed:
+>
+>     pragma Restrictions (No_Implicit_Overriding);
+>     pragma Restrictions (No_Implicit_Overloading);
+>
+> No_Implicit_Overriding would require that you write "overriding" when you
+> override a subprogram.  No_Implicit_Overloading would required that you
+> write "not overriding" when you declare a new overload.  Using the two
+> restrictions together would require that you write either "overriding" or
+> "not overriding" before each declaration.  (And maybe "overriding or not" if
+> we have to keep this one for generics.)
+
+Not quite: a totally new identifier wouldn't be protected.
+
+Besides, don't you think that defining these properly would be as hard as
+defining Explicit_Overriding? The issues of where to check certainly occur here
+as well; it's precisely them that I want to get rid of. And certainly the
+generic issues would exist.
+
+We could informally suggest such things in the AARM, but I'm pretty sure we
+wouldn't want to try to define them.
+
+> > It's mildly annoying to have to write more to be safe, but
+> > then again that's what Ada's about.
+>
+> That doesn't bother me as it would be easy to write a tool to add the
+> overriding_indicators as appropriate (I could write such a tool in a couple
+> of days).  One could argue that all these overriding_indicators would
+> degrade readability, but with the restrictions you could choose the
+> trade-off between readability and safety.
+
+Yes, its the readability issue that I think would be significant. Especially to
+anyone that hasn't struggled with the generic model.
+
+----End 3rd thread.
+----End private discussion.
 
 *************************************************************
 

Questions? Ask the ACAA Technical Agent