CVS difference for ai12s/ai12-0205-1.txt

Differences between 1.6 and version 1.7
Log of other versions for file ai12s/ai12-0205-1.txt

--- ai12s/ai12-0205-1.txt	2020/01/10 01:22:00	1.6
+++ ai12s/ai12-0205-1.txt	2020/01/11 04:32:53	1.7
@@ -1,4 +1,4 @@
-!standard 12.3(7/3)                                  20-01-06  AI12-0205-1/03
+!standard 12.3(7/3)                                  20-01-10  AI12-0205-1/04
 !standard 12.3(10)
 !standard 12.5(2.1/3)
 !standard 12.5(2.2/3)
@@ -64,6 +64,14 @@
 synonym for generic actual parameter and also for the view denoted by one,
 or the value of one.
 
+AARM Discussion: Any matching or other Legality Rules that apply to a 
+an generic actual are applied to any default_expression, \default_\subtype_mark,
+or default_name that are used for an actual.
+
+[Editor's note: Steve was unsure if the Legality Rules applied to defaults. I 
+think it is obvious (a default *is* an actual, and the Legality Rules aren't
+conditional), but it doesn't hurt to emphasize that.]
+
 Modify 12.3(10) as follows:
 
 A generic_instantiation shall contain at most one generic_association
@@ -81,70 +89,16 @@
       [or use \default_\subtype_mark];
 
 Add after 12.5(7/2):
-
-The \default_\subtype_mark, if any, shall denote a subtype in the category
-determined for the formal type.
-
-For a formal type with a \default_\subtype_mark, if the declaration depends 
-on some other formal type \F\ of the same generic_formal_part, the 
-declaration of \F\ shall also have a \default_\subtype_mark. For the purposes
-of this check, a type declared in a formal package of a generic_formal_part
-is considered a formal type of the generic_formal_part that does not have
-a \default_\subtype_mark.
-
-AARM Reason: We require this so that the defaults are useful. If this wasn't 
-true, the default could only be used if the type without a default is 
-specified as a specific actual value. For example:
-
-    generic
-      type Elem is digits <>;
-      type Arr is array (Positive range <>) of Elem or use Float_Array; -- Illegal.
-
-If this was allowed, the actual for Elem would have to be Float in order to 
-use the default. This sort of implied contract is confusing and not very 
-useful. If Elem also has a default, then both parameters can be omitted from 
-instances. [Editor's note: Bob asked for this note to be added with this wording.]
-
-The last sentence ensures that formal types that depend on a formal package
-do not allow defaults, as the formal package would have to export a specific
-type for the default to work, and this would be another form of implied 
-contract. Whether the exported type itself has a default is irrelevant, as
-there is no way to ensure that the actual instance uses it. [Editor's note: 
-If we allow formal package defaults, then we should revisit this.]
-End AARM Reason.
-
-AARM Discussion: A formal type can depend on another in many ways. Some examples
-include:
-  * the designated type of a formal access type;
-  * the component type of a formal array type;
-  * the ancestor type of a formal derived type.
-In addition, discriminants provide a variety of additional ways for dependence.
-There are enough of these that we don't want to enumerate them; 
-that would cause a future language maintenance problem (easy to forget 
-to update a rule like this if some new kind of formal is added).
-End AARM Discussion.
-
-For each formal type declaration /F/ with a /default_/subtype_mark /S/, after 
-substituting the /default_/subtype_mark for any other formal type of the same 
-generic_formal_part which appears in /F/, /S/ shall be a legal actual for the 
-substituted version of /F/.
-
-AARM Reason: This rule prevents inconsistent defaults. For example:
 
-    type Float_Array is (Positive range <>) of Float;
+The \default_\subtype_mark, if any, shall denote a subtype which is allowed as
+an actual subtype for the formal type.
 
-    generic
-      type Elem is digits <> or use Long_Float;
-      type Arr is array (Positive range <>) of Elem or use Float_Array; -- Illegal.
-
-An instantiation of this generic using defaulted formal types would be illegal.
-We expect this to be a common usage, so it doesn't make much sense to allow
-a generic that can't be instantiated as it appears to be intended.
-End AARM Reason.
+  AARM Ramification: This rule is observed at compile time of the generic_declaration,
+  and is consistent with the handling of the default_name of a formal subprogram.
+  This means that a type declared outside of the generic_declaration cannot be used
+  as the \default_\subtype_mark for a formal type that depends on any other formal 
+  type.
 
-AARM Discussion: We write the rule this way as we do not want to repeat all of 
-the requirements on actual types here.
-
 !discussion
 
 This AI proposes to allow generic formal types to have defaults. Currently,
@@ -181,55 +135,97 @@
 
 ---
 
-The consistency checking for default types has to meet two main requirements:
+We only allow default_subtype_marks that can be used directly as an actual for
+the given formal type. This ensures that an instance that uses the default is
+going to be legal and not have any hidden contracts.
+
+This rule does not allow any formal types that depend on other formal types
+of the generic to have a default_subtype_mark unless that default is another
+formal type  of the generic.
+
+We attempted to find a model that would allow types that depend on other
+formal types to have defaults.
+
+Simply allowing any subtype of the right category is tempting. Any instance
+will be detect the error, as every rule that applies to an actual type applies
+to an actual type that is specified by a default (the definition is that the
+default IS the actual type). However, this means that defaults can cause
+"hidden contracts" by adding requirements to other formals. For instance:
 
-* We don't want to repeat any of the rules about matching actuals to formals.
-  That would certainly lead to missing some, and other sorts of pestilence.
+   type Flt_Array is array (Positive range <>) of Float;
 
-* We also don't want to cause implementations to implement lots of new code - 
-  it should be fairly obvious how to implement the checks using existing code.
+   generic
+      type Element_Type is digits <>;
+      type Array_Type is array (Positive range <>) of Element_Type
+         or use Flt_Array;
+   procedure Gen is ...
 
-We settled on a rule that can "easily" be implemented by the following loop:
+An instance of Gen can only use the default if the Element_Type is of type
+Float.
 
-    for Formal_Type of Formal_Part loop
-        if Has_Default (Formal_Type)  then
-           Check_Actual_Against_Formal (Formal_Type, Default_Subtype);
-           Replace_In (Formal_Part, Formal_Type, Default_Subtype);
-        end if;
-    end loop;
-
-This loop operates on a copy of the formal part (can't modify the original).
-Check_Actual_Against_Formal does all of the checks for an actual type against 
-a formal type in any instance. Replace_In replaces the given formal type with 
-the default subtype in the entire formal part. Since a type can only depend on 
-types preceeding it, this loop will make all of the checks needed, taking into 
-account the default for earlier formal types. Note that the requirement that 
-any dependence formal type has a default ensures that for any type with a
-default, any dependencies also have an actual type. Thus, this check is exactly
-the same as one used for an instance, and thus implementers shouldn't have to
-do too much surgury to make this check.
+We considered simply requiring default types to depend only on other formal
+types that include defaults. That would allow:
 
----
+   generic
+      type Element_Type is digits <> or use Float;
+      type Array_Type is array (Positive range <>) of Element_Type
+         or use Flt_Array;
+   procedure Gen2 is ...
 
-The part of the dependence rule about formal packages is talking about a case
-like:
+But that also would allow cases where only individual defaults could be used 
+in a legal instantiation. For instance, the following would be allowed:
 
    generic
-      type Elem is digits <> or use Float;
-   package Signature is end Signature;
+      type Element_Type is digits <> or use Long_Float;
+      type Array_Type is array (Positive range <>) of Element_Type
+         or use Flt_Array;
+   procedure Gen3 is ...
+
+An instance of Gen3 would have to specify one of Element_Type or Array_Type,
+because the defaults are incompatible.
+
+Such a rule also would ban defaults that are other generic formals if the formal
+type has any dependence on another formal type.
+
+Another alternative that was considered to require all of the type defaults 
+(together) to make a legal instance, treating the other parameters as their
+original formals. That would reject Gen and Gen3, and allow Gen2.
+
+Such a rule however means that the defaults for all generic parameters have to 
+be checked as a set, rather than individually. That's different than other
+default parameters for generic units.
 
-      [Editor's note: Sorry, John. ;-)]
+Moreover, such a rule would fail if other kinds of formal parameters depend on
+types with defaults. For instance:
 
-   generic
-       with package Sig is new Signature (<>);
-       type Arr is array (Positive range <>) of Sig.Elem 
-          or use Float_Array; -- Illegal.
-    
-Here, Arr depends on a type from the formal package. We don't allow this, as
-it would be an implied contract on Sig when the default is being used. We also
-want the consistency check to work only on actual types, so having a type
-exported from a formal package that isn't an actual type involved breaks the
-intended check.
+    generic
+      type Element_Type is digits <> or use Long_Float;
+      with function Is_Positive (A : in Element_Type) return Boolean;
+    procedure Gen4 is
+
+The proposed rule would fail here as an test instance of 
+Gen4 (Long_Float, Is_Positive); would be illegal. One could imagine fixing that
+by extending the rules to default_names for formal subprograms (this would
+be compatible, as a default_name for a formal subprogram like Is_Positive
+is illegal in Ada 2012). But this seems like a major complication.
+
+We believe that any rule used here has to at a minimum meet two principles:
+
+* We don't want to repeat any of the rules about matching actuals to formals.
+  That would certainly lead to missing some, and other sorts of pestilence.
+
+* We also don't want to cause implementations to implement lots of new code - 
+  it should be fairly obvious how to implement the checks using existing code.
+
+The second point simply follows from this being a non-critical feature for
+Ada and therefore a lot of implementation complexity isn't justifiable.
+
+The simpler rule proposed here works for the use cases that have suggested
+for defaults. It also could be compatibly extended in the future to use a
+a more complex rule, preferably one that applied to all kinds of defaults
+in a generic instance. (It seems inconsistent to have special rules to allow
+type defaults to depend on other formals, but not have such rules for other
+kinds of generic formal defaults.)
 
 !example
 

Questions? Ask the ACAA Technical Agent