CVS difference for ais/ai-20218.txt

Differences between 1.5 and version 1.6
Log of other versions for file ais/ai-20218.txt

--- ais/ai-20218.txt	2003/07/26 03:26:03	1.5
+++ ais/ai-20218.txt	2003/09/18 03:28:31	1.6
@@ -1,4 +1,4 @@
-!standard 8.3(26)                                    03-06-06  AI95-00218-03/01
+!standard 8.3(26)                                    03-09-17  AI95-00218-03/02
 !class amendment 03-06-06
 !status work item 03-06-06
 !status received 03-06-06
@@ -87,7 +87,7 @@
 The general idea is that subprogram declarations that are overriding are
 prefixed with "overriding", whereas subprogram declarations that are prefixed
 "not overriding" must not override another routine. The same applies to
-renamings and generic instantiations.
+subprogram bodies, renamings, and generic instantiations.
 
 If no prefix is given, the Ada 95 rules are used. This has the effect of
 turning off checking for that declaration. For instance, in a generic unit with
@@ -102,74 +102,55 @@
 not visibly overloaded but turns out to be overloaded when the full
 type declaration occurs. Therefore, we define the checks to be
 made at the point of the declaration or clause with the prefix. For the case
-in question, no prefix would be given on the visible declaration.
+in question, no prefix would be given on the visible declaration. The prefix
+could be given on the body, if desired.
 
-In order to insure that the overriding is in fact declared, we introduce
-an overriding_clause which consists of of a copy of the
-specification with an overriding prefix. 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. Typically, these
-clauses will appear in the private part prefixed by "overriding".
-
 !wording
 
-In 2.9(3) as modified by AI 284 add the following to the list of nonreserved
+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
+Change the syntax in 6.1 to read:
 
 overriding_indicator ::= [not] overriding
 subprogram_declaration ::=
                [overriding_indicator] subprogram_specification ;
 abstract_subprogram_declaration ::=
    [overriding_indicator] subprogram_specification is abstract;
-overriding_clause ::= overriding_indicator subprogram_specification ;
 
-Add to 8.3 after paragraph 23:
+Change the first two lines of 6.3(2) to read:
 
-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 an overriding_indicator 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. Its profile shall be fully conformant with the profile
-of the subprogram_declaration, abstract_subprogram_declaration or
-subprogram_renaming_declaration.
+subprogram_body ::=
+               [overriding_indicator] subprogram_specification
 
 Add to 8.3 after paragraph 26:
 
 If an explicit declaration of an operation by a subprogram_declaration,
-abstract_subprogram_declaration, subprogram_renaming_declaration or
-generic_instantiation of a subprogram has the overriding_indicator "overriding"
-then it shall override another homograph at the point of the declaration. If an
-explicit declaration of an operation by a subprogram_declaration,
-abstract_subprogram_declaration, subprogram_renaming_declaration or
-generic_instantiation of a subprogram has the overriding_indicator "not
-overriding" then it shall not override another homograph at the point of the
-declaration. These rules do not apply in a generic_declaration. 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.
-
-If an overriding_clause has the overriding indicator "overriding" then the
-corresponding operation shall override another homograph at the point of the
-declaration. If an overriding_clause has the overriding indicator "not
-overriding" then the corresponding operation shall not override another
-homograph at the point of the declaration. These rules do not apply in a
-generic_declaration. 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.
+abstract_subprogram_declaration, subprogram_body, subprogram_renaming_declaration or
+generic_instantiation of a subprogram has an overriding_indicator, then:
+  * the operation shall be a primitive operation for some type;
+  * if the overriding_indicator is "overriding", then it shall override
+    another homograph at the point of the declaration;
+  * if the overriding_indicator is "not overriding", then it shall not override
+    another homograph (at any point).
+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:
-Whether a homograph is implicitly declared after the declaration or
-overriding_clause (see 7.3.1 to see how this can happen) has no impact on these
-checks. Thus, the overriding_indicator accurately reflects the overriding state
-of the operation at the point of the declaration or clause.
+The "overriding" and "not overriding" rules differ slightly. For "overriding",
+we want the indicator to reflect the overriding state at the point of the
+declaration; otherwise the indicator would be 'lying'. Whether a homograph is
+implicitly declared after the declaration (see 7.3.1 to see how this can happen)
+has no impact on this check. However, "not overriding" is different; 'lying'
+would happen if a homograph declared later actually is overriding. So, we
+require this check to take into account later overridings. That can be
+implemented either by 'peeking', or by rechecking when additional operations
+are declared.
+
+The 'no lying' rules are needed to prevent a subprogram_declaration and
+subprogram_body from having contradictory overriding_indicators.
 
 Change the syntax in 8.5.4 to read
 
@@ -207,11 +188,11 @@
 !discussion
 
 The forms "overriding" and "not overriding" 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,
+subprogram_declaration (and other forms) 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,
 formal subprogram parameters and subprogram body stubs. However, we do want
-them to apply to abstract subprograms, to renaming and to generic
+them to apply to abstract subprograms, to bodies, to renaming and to generic
 instantiations. For example
 
    overriding
@@ -223,14 +204,12 @@
    overriding
    procedure Pup is new Pap(P1 => A1, P2 => A2);
 
-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. 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.
+Overriding indicators are also allowed on subprogram bodies. 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. An
+overriding indicator in this case can show the reader that overriding has
+occurred (and the compiler can check this intent). 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).
@@ -245,12 +224,107 @@
 group.
 
 
+An important principle is that an overriding_indicator never 'lie' to the user.
+That is, it should never be the case that an operation is marked 'overriding'
+when it is not, nor should be marked 'not overriding' when it is.
+
+This matters when private types are brought into the picture.
+
+Presume type T2 has an operation Foo, but its parent type T1 does not. Then
+
+package P is
+   type T is new T1 with private;
+   procedure Foo; -- Can't give 'overriding' here.
+private
+   type T is new T2 with ...;
+end P;
+
+We don't allow giving 'overriding' on Foo, as it is not an overriding
+operation of the partial view. To a user looking at the package from outside
+without seeing the private part, there is no Foo to override from. So, allowing
+the code to say otherwise would be confusing.
+
+On the other hand, we don't allow giving 'not overriding' on Foo, either. That
+would be a worse lie, as the routine eventually will become overriding when
+the full declaration is given.
+
+The indicator 'overriding' can be given on the subprogram_body, if desired.
+
+If T1 does have the operation Foo, then an overriding indicator can (and
+should) be given for the partial view. Thus
+
+package P is
+   type T is new T1 with private;
+   overriding
+   procedure Foo;      -- partial view is overriding
+private
+   type T is new T2 with ...;
+end P;
+
+Later overriding can occur not just in the private part, but at various other
+locations as well (because of the rules of 7.3.1(6)). This later overriding
+is ignored when checking 'overriding' (because otherwise the declaration
+would lie), but is taken into account when checking 'not overriding' (again
+to prevent lying).
+
+An example of how this could happen:
+
+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);     -- Illegal, 'Op' is not overriding here.
+                               -- The primitive 'Op' does not become visible
+                               -- until the private part.
+    package Nested is
+        type NNT is new T with null record;
+        overriding
+        procedure Op (Y : NNT); -- Illegal, 'Op' is not overriding here.
+                                -- Only the body of Nested has
+                                -- visibility on primitive 'Op'.
+    end Nested;
+private
+    -- P.C.Op overrides P.Op here (P.Op is inherited here).
+end P.C;
 
-Subtle situations occur with generics and private types. We will consider
-generics first.
+package body P.C is
+    overriding
+    procedure Op (Y : NT) is ... -- OK.
+    package body Nested is
+        -- P.C.Nested.Op overrides P.Op here (P.Op is inherited here).
+        overriding
+        procedure Op (Y : NNT) is ... -- OK
+    end Nested;
+end P.C;
 
-Overriding_indicators are not checked generic_declarations or instance bodies,
-but are checked in generic bodies and instance specification.
+In this situation, the overriding_indicators have to be given on the bodies.
+Note that in the case of Nested.Op, the overriding takes place in the body,
+so no earlier overriding_indicator could be supported. Examples like these
+are a second reason that overriding_indicators are allowed on bodies.
+
+Some drafts of this AI supported a separate clause to allow giving the
+overriding_indicator at the point where the overriding actually occurred.
+This clause doesn't seem necessary. For tagged types, it would only be needed
+in cases (like the first one) where we wish to make the same operations visible
+in two branches of the tree, while obscuring the common ancestory. Typically,
+it would be better to hoist the operations to the common ancestor; in any
+case, this locution is likely to be rare. Thus, we provide a way to specify
+overriding for it (by putting it on the body), but we do not go out of our
+way to make it easy.
+
+
+There are also issues with generic units.
+
+Overriding_indicators are checked following the standard Ada 95 rule (12.3(11)).
+That is, they are checked based on the properties of the formals in the
+generic declaration and body, and are rechecked based on the properties of
+the actuals in the instance specification.
 
 Consider
 
@@ -259,27 +333,14 @@
 package Gen is
     type DGT is new GT with private;
     overriding
-    procedure Op (Z : DGT); -- OK, GT must have an Op.
+    procedure Op (Z : DGT); -- Illegal, GT does not have an Op.
 private
     -- ...
 end Gen;
-
-Giving an overriding_indicator in this way is legal. The effect is be to force
-all actual types for GT to have an operation Op. This effectively modifies the
-contract of the generic to include that operation.
 
-It has been suggested that this "implicit contract" is confusing and hard to
-see. Perhaps, but many of the Legality Rules in Ada 95 have the effect of
-defining an implicit contract. For instance, even without "overriding", the
-generic above (Gen) has an implicit contract that GT has the same accessibility
-level as the instantiation of Gen. This contract is far less visible than
-the keywords "overriding" are.
-
-In addition, it isn't possible to completely eliminate implicit contracts
-caused by overriding_indicators. If we enforced the rule in
-generic_declarations as well as instances, the declaration of Op would be
-illegal. This would eliminate the "implicit contract" for the use of
-"overriding". But the situation for "not overriding" is different. Consider:
+Giving an overriding_indicator in this way is illegal. This avoids an
+"implicit contract" that GT have an Op. However, we still have an
+implicit contract when not overriding is used. Consider:
 
 generic
     type GT is tagged private;
@@ -293,22 +354,55 @@
 
 This unit is legal, as Gen2.DGT does not have an Op operation. However, since
 Legality Rules are rechecked in the instance, an instantiation of Gen2 would
-be illegal if GT in fact had an Op primitive subprogram. So the implicit
-contract has reappeared.
+be illegal if GT in fact had an Op primitive subprogram.
 
-We could eliminate this problem by not rechecking at all in instances. However,
-this means that overriding indicators may not actually reflect reality in
-instances. It would be very odd indeed if an instance of Gen2 above had an
-Op that was actually overriding, even though it is declared to be not
-overriding.
+Because of this strange asymetrical result, we also considered two other rules:
+  1) The standard 12.3(11) rule (with checking in the private part of the instance);
+  2) As (1), except that no checking is done in the generic_declaration;
+  3) As (1), except that no checking is done in the instance.
+
+(1) does not require rechecking of 'overriding' in the instance (it cannot
+fail), while it does require checking of 'not overriding' in both the
+declaration and instance. (2) and (3) does not require rechecking (each check
+is made only once).
+
+(3) eliminates "implicit contracts" completely, but overriding_indicators may
+very well be 'lying' about the situation in the instance. Thus, we rejected
+this possibility.
 
+That means that we are stuck with "implicit contracts" in some cases. It has
+been suggested that "implicit contract"s are confusing and hard to
+see. Perhaps, but many of the Legality Rules in Ada 95 have the effect of
+defining an implicit contract. For instance, even without "overriding", the
+generics above (Gen and Gen2) have an implicit contract that GT has the same
+accessibility level as the instantiation of Gen. This contract is far less
+visible than the keyword "overriding" is.
+
 Note that if a user does not want an implicit contract (as in a mix-in,
 perhaps), they simply can omit any overriding_indicators.
+
+Deciding between (1) and (2) is hard. (2) allows "implicit contracts" for both
+"not overriding" and "overriding", and thus makes their behavior more
+symetrical. If (2) was adopted, the original example:
+
+generic
+    type GT is tagged private;
+package Gen is
+    type DGT is new GT with private;
+    overriding
+    procedure Op (Z : DGT); -- OK, GT must have an Op.
+private
+    -- ...
+end Gen;
+
+This would be legal if (2) is adopted. The effect would be to force
+all actual types for GT to have an operation Op.
 
-Thus, given that Ada 95 already has implicit contracts, and these are clearly
-the most useful of the three options, we have adopted the rules as specified
-in the Wording section.
+While this looks appealing from a consistency standpoint, it is questionable
+how useful it is. Therefore, we have adopted the standard Ada rule (which
+at least is consistent with the rest of the language).
 
+
 A related situation is where the formal type is derived so that there may be
 a number of known primitive operations. Consider:
 
@@ -317,18 +411,23 @@
 package Gen is
     type DGT is new GT with private;
     overriding
-    procedure Op (Z : DGT); -- OK.
+    procedure Op (Z : DGT); -- OK if T has an Op.
 private
     -- ...
 end Gen;
 
 If the type T has Op as an operation then there is not an added contract (all
 possible types will have Op). However, if T does not have Op as a primitive,
-then this implies a contract that the actual does have Op. Again, if this is
-not desired, omitting "overriding" returns the checking to the Ada 95 rules.
+the generic unit is ileggal.
+
 
-A somewhat similar situation arises with private types. Thus consider:
+Overriding_Indicators are allowed on all types. We cannot restrict them to
+just tagged types, because doing so would lead to contract model problems.
+While the primary use for this feature is with tagged types, we do need to
+insure that untagged types do not cause problems.
 
+Consider:
+
 package P is
    type T is private;
    function "+" (Left, Right: T) return T;
@@ -348,181 +447,50 @@
 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 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 an overriding indicator
-and in the full view we want to give the true state of affairs. Thus
+partial view. This is similar to the private extension case discussed
+earlier. 'Overriding' would be illegal on both examples, while 'Not overriding'
+would be allowed only on the second one (which would constrain the
+implementation). Again, it is permissible to put an overriding_indicator
+on the body of "+" to indicate whether or not it is an overriding routine.
 
-package P is
-   type T is private;
-   function "+" (Left, Right: T) return T; -- overriding not visible
-private
-   type T is range 0 .. 100;
-   overriding
-   function "+" (Left, Right: T) return T;  -- now we know
-end P;
 
-Checking is only performed when an overriding indicator is given. Thus,
-in this example, no check is performed for the declaration, and one is
-performed for the overriding_clause.
-
-Overriding_clauses are only allowed when the original declaration does not
-have an overriding_indicator. This restriction is not strictly necessary
-(there is no problem with checking overriding in multiple places), but it
-avoids lying to the user. The partial view should not explicit state something
-that is false; for instance:
+It is possible for a routine to be primitive for more than one type and
+overriding for one of the types. Such a routine is considered 'overriding'.
+For instance:
 
-package P is
-   type T is private;
-   not overriding
-   function "+" (Left, Right: T) return T; -- overriding not visible
-private
-   type T is range 0 .. 100;
-   overriding
-   function "+" (Left, Right: T) return T;  -- Overriding_clause not allowed.
-end P;
-
-Similarly, there is no value to repeating the overriding_indicator. It would be
-more likely to confuse the reader than to provide any value.
-
-An overriding_clause is restricted to the private part of the
-unit that contains the declaration. This eases the requirements on checking
-that all primitive operations have appropriate overriding_indicators or clauses.
-(While we're not including such checks as part of this proposal, they are
-likely to be a common part of coding style requirements.) If overriding_clauses
-could be given other than in the private part, checking that all overridings
-are explicitly declared would require looking in bodies and nested units.
-
-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. 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, it is not possible to declare an
-instantiation as overriding if the instantiation is in the visible part,
-it is not overriding for the partial view, and the operation turns out to be an
-overriding one. 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:
-
-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;
-
-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;
-
-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 can (and
-should) be given for the partial view. Thus
+package Foo is
 
-package P is
-   type T is new T1 with private;
-   overriding
-   procedure Foo;      -- partial view is overriding
-private
-   type T is new T2 with ...;
-end P;
+    type Root is tagged private;
 
-We check overriding based on the state at the point of the declaration. That is
-done so that the indicator always reflects the true state of the declaration.
-However, an operation that is not overriding at some point can later become
-overriding (because of the rules of 7.3.1(6)). This later overriding is ignored
-for the purposes of checking overriding.
+    type Counter is range 0 .. 10_000;
 
-An example of how this could happen:
+    not overriding
+    procedure Add (Obj : in out Root; Cnt : in Counter);
+        -- Primitive on both Root and Counter.
 
-package P is
-    type T is tagged private;
-private
-    type T is ...
-    procedure Op (Y : T);
-end P;
+    type Child is new Root with private;
 
-package P.C is
-    type NT is new T with null record;
     overriding
-    procedure Op (Y : NT);     -- Illegal, 'Op' is not overriding here.
-                               -- The primitive 'Op' does not become visible
-                               -- until the private part.
-    package Nested is
-        type NNT is new T with null record;
-        overriding
-        procedure Op (Y : NNT); -- Illegal, 'Op' is not overriding here.
-                                -- Only the body of Nested has
-                                -- visibility on primitive 'Op'.
-    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;
+    procedure Add (Obj : in out Child; Cnt : in Counter);
+        -- Primitive on both Child and Counter, and overriding (for Child).
 
-In this situation, the types NT and NNT are not private types and so there
-is no possibility of an overriding clause. Still, the overriding_indicators
-are not legal on these declarations. We probably simply should omit the
-overriding_indicators to avoid breaking the abstraction (privateness)
-of the original type P.T.
+private
+    type Root is tagged record
+      Cnt : Counter := 0;
+    end record;
 
-Contrast this with
+    type Child is new Root with null record;
+end Foo;
 
-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;
-        overriding
-        procedure Op (Y : NT); -- Illegal, this still doesn't override anything.
-    end Nested;
-private
-    type NT is new T with null record;
-    -- P.C.Op overrides P.Op here (P.Op is inherited here).
-    overriding
-    procedure Op (Y : NT); -- OK.
-end P.C2;
+The second "Add" is overriding: the primitive Add is inherited (as it is
+declared before the declaration of Child); it is overriding (because it has
+the same profile as the inherited routine); and it is primitive for two
+types (because it is declared in the same package specification as Counter,
+so it is primitive for both Child and Counter.)
 
-Here the types NT and NNT are private types and so overriding clauses
-are allowed. However, such a clause for Nested.Op would have to go in the
-body, which is not allowed. This seems OK, this sort of structure is likely
-be rare. Indeed, the error is likely to catch as many bugs as it causes,
-since it points out the visibility nightmare that the user has gotten
-themselves into.
+A routine is considered overriding if it is overriding for any type. This
+is the most natural interpretation, but it may cause surprises if a routine
+is inherited from some untagged type.
 
 
 This proposal only increases the safety of Ada programs if the programmer uses
@@ -532,25 +500,22 @@
 
 We considered having a standard pragma in order to require the use of
 indicators in declarations. One suggestion was a new Restriction:
-    pragma Restrictions (Indicators_Required_for_Primitive_Operations);
+    pragma Restrictions (Indicators_Required);
 with the semantics that any explicit declaration of a primitive operation
-must have an overriding_indicator or a overriding_clause.
+must have an overriding_indicator (either on the specification or the body).
 
 However, while this seems appealing at first glance, there are a number of
 issues:
-1) The check has to be delayed until the end of the enclosing declarative
-part, as a later overriding_clause may be seen.
-2) It is possible to declare a type where the overridden declaration is not
-inherited until the body (one is given above). In such a case, this pragma
-would require using "not overriding" on the overriding declaration in the
-specification, which is an outright lie. (This case should be rare, however.)
-3) Restrictions apply inside of generic units. However, many generic units
+1) The check has to be delayed until the end of the compilation of the body,
+as a overriding_indicator may be seen on the body.
+2) Restrictions apply inside of generic units. However, many generic units
 will prefer to avoid implicit contracts by avoiding the use of
-overriding_indicators.
-4) This rules apply to all primitive operations, including untagged ones.
+overriding_indicators. Moreover, there are examples where no indicator can
+be given (as shown above).
+3) This rules apply to all primitive operations, including untagged ones.
 The value of overriding indicators is much less for untagged types, and
 giving them for all operators could be a burden.
-5) Restrictions are generally partition-wide, and many compilers do not
+4) Restrictions are generally partition-wide, and many compilers do not
 support their use on individual units. The adoption of overriding_indicators
 is likely to be piece-meal, and it would be valuable to use them in some
 subsystems while still including other subsystems that do not.
@@ -562,7 +527,7 @@
 intent is not followed). The vast majority of problems of this sort are
 cases where Finalize or another overridden routine is not called when the
 programmer fully expects it to be called. The compiler knows otherwise,
-but cannot tell.
+but cannot tell the programmer of their mistake.
 
 
 We considered using further pragmas rather than syntax since syntax was
@@ -581,10 +546,15 @@
 program maintenance if the identifier is not included and including it seems
 a burden.
 
-In addition, a pragma solution does not cleanly handle the cases that
-overriding_clauses are provided to handle. In this case, the pragmas must
-be separated from the declarations (presuming we are unwilling to violate
-privateness). This makes checking significantly more expensive. Moreover,
+In addition, a pragma solution does not cleanly handle specifying
+overriding for a body. Generally, similar pragmas (like Inline) are not
+allowed on bodies. Putting the pragma inside the body would be weird;
+putting it before it would violate the normal rules for pragmas.
+Putting the pragma after the body would separate it a long ways from the
+specification that it applied to.
+
+We considered an alternative that allowed the pragmas to appear anywhere.
+This makes checking significantly more expensive. Moreover,
 because of overloading, some way of limiting the effect of the pragma is
 needed. Two options were considered:
 
@@ -622,7 +592,7 @@
    procedure Pup overrides is new Pap(P1 => A1, P2 => A2);
 
 However, it proved difficult to resolve the different grammatical forms and
-the need to indicate optional overriding as well. Placing the indicator at
+the need to indicate not 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 use of "not overriding" is
@@ -672,7 +642,7 @@
 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.
+why having the default be safe gets us into trouble).
 
 *************************************************************
 
@@ -1091,6 +1061,167 @@
 Are there other cases where the overriding will only occur in the body
 that we need to deal with?  (The only one I saw offhand was the implicit
 body case.)
+
+*************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, September 17, 2003  10:22 PM
+
+The new version of AI-218-03 [version /02] that I just posted for comment
+contains six major changes:
+
+   -- overriding_indicators are allowed on bodies; (minor open issue:
+      should these be allowed on stubs? They are allowed on the actual subunit,
+      so allowing them on stubs is redundant, but more consistent.)
+   -- wording is added so that overriding_indicators must never 'lie'; that
+      means that a 'not overriding' subprogram must never become overriding;
+   -- wording was adjusted so that a routine primitive for more than one type
+      can be considered 'overriding' (actually, this didn't require a change, but
+      we now explicitly intend this result);
+   -- wording is added so that overriding_indicators are only allowed on primitive
+      operations;
+   -- generics were changed to use the 'standard' mechanism, as discussed at the
+      last meeting;
+   -- overriding_clauses were removed.
+
+The discussion also has been completely overhauled.
+
+The removal of overriding_clauses needs a bit of explanation that I didn't
+want to crowd into the !disucssion.
+
+At the meeting, we wondered if we still needed overriding_clauses, given that
+it is now possible to give overriding_indicators on bodies. The feeling was
+that they were not necessary, but there was concern that they may be necessary
+in generic units.
+
+Clearly, by depending on overriding_indicators on bodies, we have a simpler
+change. It is true that the indicator may turn out to be given very late, but
+this cannot be worse than the current situation. And in virtually all tagged
+type cases (the primary use for the feature), the overriding_indicator can be
+given on the subprogram's specification. So, there doesn't seem to be enough
+need for the complication of overriding_clauses.
+
+Let's look at this in more detail.
+
+First, 'not overriding' can *always* be given on the subprogram specification.
+By the 'no lying' rule, you are not allowed to give it if in fact the routine
+is overriding at any point in the future. Thus, if you can use 'not overriding'
+at all, you can give it on the specification (it cannot change). That is true
+both inside and outside of generics.
+
+Second, the no overriding_indicator case is unchanged from Ada 95. No more
+needs to be said about that.
+
+So, all of the interesting cases involve the 'overriding' indicator. Let's look
+at them. First of all, virtually all tagged type cases can put the 'overriding'
+indicator on the specification. That is easily done by putting the overriding
+into the private part. Some style guides suggest that as a matter of course
+(because the user has no need to know whether or not a particular operation is
+overridden). But it almost always is an available option for tagged types.
+
+For instance, the following example is drawn from Claw:
+
+    package Claw is
+        type Root_Window_Type is abstract tagged private;
+        procedure Move (Window : in out Root_Window_Type;
+                        Where  : in Point_Type) is abstract;
+    end Claw;
+
+    package Claw.Basic_Window is
+        type Basic_Window_Type is new Claw.Root_Window_Type with private;
+        not overriding function Is_Valid (Window : Basic_Window_Type) return Boolean;
+    private
+        type Basic_Window_Type is new Claw.Root_Window_Type with ...;
+        overriding
+        procedure Move (Window : in out Root_Window_Type;
+                        Where  : in Point_Type);
+    end Claw.Basic_Window;
+
+It is OK to put the overriding into the private part. Note that the overriding
+clause here will catch the cut-and-paste error I made here (unintentially, I
+might add, one that has happened to me a number of times in real code), as the
+routine isn't primitive.
+
+In the case that the operation is not visible in the partial view, but is
+desired to be made visible, we cannot use this paradym. For instance:
+
+    package Claw.Basic_Window.Menu is
+        type Menu_Window_Type is new Claw.Root_Window_Type with private;
+        overriding
+        function Is_Valid (Window : Basic_Window_Type) return Boolean;
+	     -- Illegal, not overriding here, will become overriding in the private part.
+    private
+        type Menu_Window_Type is new Claw.Basic_Window.Basic_Window_Type with ...;
+        overriding
+        procedure Move (Window : in out Menu_Window_Type;
+                        Where  : in Point_Type);
+    end Claw.Basic_Window.Menu;
+
+In this case, the overriding_indicator has to be placed on the body of
+Is_Valid. Note, also that 'not overriding' is not allowed on Is_Valid, either,
+as it will become overriding later.
+
+This doesn't seem too bad -- making 'hidden' operations visible this way should
+be rare (usually the operations are hidden for a reason!).
+
+Untagged types are pretty similar (although more cases fall into the second
+category). But since this feature was designed mainly for tagged types, I find
+it hard to get excited about that.
+
+Turning to generic units. If no formals are involved, the situation is the same
+as for any other package (as described above). So we only need consider
+formals. The rules state that the legality rules are checked based on the
+properties of the formal. That means that 'overriding' is only legal in cases
+where the formal being derived from has the overriding routine. For tagged
+types, that means that the formal has to be a formal derived type.
+
+    generic
+        type Some_Window_Type is new Claw.Root_Window_Type with private;
+    package Claw.Mixin_Generic is
+        type Mixin_Window_Type is new Some_Window_Type with ...;
+        overriding
+        procedure Move (Window : in out Mixin_Window_Type;
+                        Where  : in Point_Type);
+    end Claw.Mixin_Generic;
+
+If a type is directly derived (as Mixin_Window_Type is above), 'overriding' can
+always be given on the routine specification. (The instance cannot change this
+legality.) In order to not be able to give this in the spec, we again have to
+turn to a private extension:
+
+    generic
+        type Some_Window_Type is new Claw.Root_Window_Type with private;
+    package Claw.Another_Mixin_Generic is
+        type Another_Mixin_Window_Type is new Claw.Root_Window_Type with private;
+        overriding
+        function Is_Valid (Window : Another_Mixin_Window_Type) return Boolean;
+	     -- Illegal, not overriding here.
+        overriding
+        procedure Move (Window : in out Another_Mixin_Window_Type;
+                        Where  : in Point_Type); -- OK
+    private
+        type Another_Mixin_Window_Type is new Some_Window_Type with ...;
+    end Claw.Another_Mixin_Generic;
+
+We cannot give the overriding_indicator on Is_Valid, as that function is not
+primitive for the formal type. Indeed, we cannot give it on the body, either,
+for the same reason. We cannot have a 'hidden contract' requiring an overriding
+routine. So we must omit the overriding_specification.
+
+Note that we can give 'not overriding' on Is_Valid's specification, and this
+does have the effect of a hidden contract. That is, we cannot instante
+Another_Mixin_Generic with Basic_Window_Type - the recheck of the instance will
+fail. (We could put 'not overriding' on the body, where it essentially will be
+ignored. Perhaps we need to disallow the use of 'not overriding' in a body? It
+could only fail if it was given on a routine imported, like Move above, which
+is relatively unlikely.)
+
+So, its clear that a overriding_clause is even less useful for the generic unit
+than it is for a normal unit. (That is, the comments from the meeting are
+backwards: an overriding_clause is only useful for non-generic types.)
+
+Thus, I deleted it completely, thus simplifying the presentation quite a bit.
+Comments welcome.
 
 *************************************************************
 

Questions? Ask the ACAA Technical Agent