CVS difference for ai05s/ai05-0153-2.txt

Differences between 1.2 and version 1.3
Log of other versions for file ai05s/ai05-0153-2.txt

--- ai05s/ai05-0153-2.txt	2009/10/18 03:09:36	1.2
+++ ai05s/ai05-0153-2.txt	2009/10/23 06:06:31	1.3
@@ -8,8 +8,8 @@
 
 !summary
 
-Add list scalar constraints to the language, and extend the available discriminant
-constraints.
+Add list scalar constraints to the language, and extend the available
+discriminant constraints.
 
 !problem
 
@@ -39,25 +39,28 @@
 
 list_constraint ::= when discrete_choice_list
 
-[Author's note: I used "when" and "discrete_choice_list" here to be consistent with
-other parts of the language. We could use other syntaxes, but that would just make
-it harder to remember the correct syntax IMHO.]
-
-A value *belongs* to the discrete_choice_list of a list_constraint if it is of the type of 
-the choices of the list, and it is either equal to one of the expressions of the list or
-it belongs to one of the discrete_ranges of the list. A value *satisfies* a list_constraint
-if it belongs to the discrete_choice_list of the constraint. The *lower bound* of a list_constraint
-is the smallest value used in an expression or the lower bound of a discrete range in the
+[Author's note: I used "when" and "discrete_choice_list" here to be consistent
+with other parts of the language. We could use other syntaxes, but that would
+just make it harder to remember the correct syntax IMHO. Alternatives that have
+turned up include using "with" or "in" here. See also the discussion.]
+
+A value *belongs* to the discrete_choice_list of a list_constraint if it is of
+the type of the choices of the list, and it is either equal to one of the
+expressions of the list or it belongs to one of the discrete_ranges of the list.
+A value *satisfies* a list_constraint if it belongs to the discrete_choice_list
+of the constraint. The *lower bound* of a list_constraint is the smallest value
+used in an expression or the lower bound of a discrete range in the
 discrete_choice_list of the constraint. The *upper bound* of a list_constraint
-is the largest value used in an expression or the lower bound of a discrete range in the
-discrete_choice_list of the constraint. A list_constraint is *discontiguous* if there exists
-a value that belongs to the range defined by the lower and upper bound of the constraint.
-A scalar subtype is *discontiguous* if it has a discontiguous list_constraint.
-
-AARM Note: We require staticness for the discrete_choices, so the lower and upper bounds can
-be determined at compile-time (we don't want to have to do a complex calculation to determine
-S'First). This also allows us to make legality depend on whether the list_constraint is
-contiguous.
+is the largest value used in an expression or the lower bound of a discrete
+range in the discrete_choice_list of the constraint. A list_constraint is
+*discontiguous* if there exists a value that belongs to the range defined by the
+lower and upper bound of the constraint. A scalar subtype is *discontiguous* if
+it has a discontiguous list_constraint.
+
+AARM Note: We require staticness for the discrete_choices, so the lower and
+upper bounds can be determined at compile-time (we don't want to have to do a
+complex calculation to determine S'First). This also allows us to make legality
+depend on whether the list_constraint is contiguous.
 
 Add after 3.5(5):
 
@@ -68,18 +71,19 @@
 
 Legality Rules
 
-An others choice may not appear in a discrete_choice_list used in a choice_list_constraint.
+An others choice may not appear in a discrete_choice_list used in a
+choice_list_constraint.
 
-[Author's note: We probably could figure out a useful meaning for "others" in this
-case, but it is unlikely to be intuitive.]
+[Author's note: We probably could figure out a useful meaning for "others" in
+this case, but it is unlikely to be intuitive.]
 
 The type of a subtype_indication containing a list_constraint shall be discrete.
 
-[Author's note: This concept could be extended to all scalar types, but that is dubious
-as equality operations on real types are often not recommended; it seems bad to build
-bad practice into the language. Restricting real choice_lists to only ranges would fix
-this, but seems inconsistent with the rest of the language. Also, allowing real choice_lists
-would require separating the syntax.]
+[Author's note: This concept could be extended to all scalar types, but that is
+dubious as equality operations on real types are often not recommended; it seems
+bad to build bad practice into the language. Restricting real choice_lists to
+only ranges would fix this, but seems inconsistent with the rest of the
+language. Also, allowing real choice_lists would require separating the syntax.]
 
 The expressions and discrete_ranges of the discrete_choice_list of a list_constraint
 shall be static.
@@ -89,15 +93,17 @@
 
 Modify 3.5(7):
 
-A constrained scalar subtype is one to which a range constraint {or list constraint}
-applies. The *range* of a constrained scalar subtype {with a range constraint} is the range
-associated with the range constraint of the subtype. The *range* of a constrained scalar
-subtype {with a list constraint} is the range determined by the lower bound and upper bound
-of the constraint. The *range* of an unconstrained scalar subtype is the base range of its type.
+A constrained scalar subtype is one to which a range constraint {or list
+constraint} applies. The *range* of a constrained scalar subtype {with a range
+constraint} is the range associated with the range constraint of the subtype.
+The *range* of a constrained scalar subtype {with a list constraint} is the
+range determined by the lower bound and upper bound of the constraint. The
+*range* of an unconstrained scalar subtype is the base range of its type.
+
+[Author's note: Most places where the range of a list constraint would be used
+have special rules so that we don't actually use it. We define it so that
+S'First and S'Last are well-defined.]
 
-[Author's note: Most places where the range of a list constraint would be used have special
-rules so that we don't actually use it. We define it so that S'First and S'Last are well-defined.]
-
 Replace 3.5(8) with:
 
 A range is compatible with a scalar subtype S if and only if:
@@ -107,36 +113,39 @@
   * S is unconstrained or has a range constraint and each bound of the range belongs to
     the range of the subtype.
 
-A range_constraint is compatible with a scalar subtype if and only if its range is
-compatible with the subtype.
+A range_constraint is compatible with a scalar subtype if and only if its range
+is compatible with the subtype.
 
 A list_constraint is compatible with a scalar subtype if and only if
-  * the value of each expression of the discrete_choice_list satisfies the list constraint
-    of the subtype, or if the subtype does not have a list constraint, belongs to the
-    range of the subtype; and
+  * the value of each expression of the discrete_choice_list satisfies the list
+    constraint of the subtype, or if the subtype does not have a list
+    constraint, belongs to the range of the subtype; and
   * each range of the discrete_choice_list is compatible with the subtype.
 
 AARM Discussion:
 
-These rules are intended so that a user (and compiler) only need worry about the most
-recent subtype declaration. The elaboration of a scalar subtype will fail if its
-constraint includes values outside of those that satisfy its parent subtype.
+These rules are intended so that a user (and compiler) only need worry about the
+most recent subtype declaration. The elaboration of a scalar subtype will fail
+if its constraint includes values outside of those that satisfy its parent
+subtype.
 
-This means that legality rules and the definition of dynamic semantics for the use of
-list_constraints do not have to worry about ancestors of the type
+This means that legality rules and the definition of dynamic semantics for the
+use of list_constraints do not have to worry about ancestors of the type
 
 End AARM Discussion.
 
 Add after 3.5(9):
 
-The elaboration of a list_constraint consists of the elababoration of the discrete_choice_list.
-Expressions and discrete_ranges of the discrete_choice_list are evaluated in an arbitrary
-order, and are converted to the type of the subtype_mark of the subtype_indication which
-contains the list_constraint.
-
-[Author's note: Should S'Range be illegal/raise Program_Error if the subtype has a discontiguous
-list constraint? It's a dubious construct, but since you can always write it explicitly, it's
-hard to say that it should be illegal.]
+The elaboration of a list_constraint consists of the elababoration of the
+discrete_choice_list. Expressions and discrete_ranges of the
+discrete_choice_list are evaluated in an arbitrary order, and are converted to
+the type of the subtype_mark of the subtype_indication which contains the
+list_constraint.
+
+[Author's note: Should S'Range be illegal/raise Program_Error if the subtype has
+a discontiguous list constraint? It's a dubious construct, but since you can
+always write it explicitly (it's defined to be equivalent to S'First..S'Last),
+it's hard to say that it should be illegal.]
 
 Add as the last sentence of 3.6(9):
 
@@ -144,61 +153,67 @@
 
 Add as the last sentence of 3.6(21):
 
-The elaboration of an array_type_definition raises Program_Error if the index subtype is a
-discontiguous subtype.
+The elaboration of an array_type_definition raises Program_Error if the index
+subtype is a discontiguous subtype.
 
-AARM Reason: We don't want to create "holey" array types. By raising Program_Error, we prevent
-generic contract problems. But we also have a legality rule so when it is statically known
-(outside of a generic) we detect the problem at compile-time.]
+AARM Reason: We don't want to create "holey" array types. By raising
+Program_Error, we prevent generic contract problems. But we also have a legality
+rule so when it is statically known (outside of a generic) we detect the problem
+at compile-time.]
 
 Add after 3.6.1(5):
 
-The discrete_range of an index_constraint shall not statically denote a discontiguous subtype.
+The discrete_range of an index_constraint shall not statically denote a
+discontiguous subtype.
 
 Add as the last sentence of 3.6.1(8):
 
-The elaboration of an index_constraint raises Program_Error if any discrete_range is a
-discontiguous subtype.
+The elaboration of an index_constraint raises Program_Error if any
+discrete_range is a discontiguous subtype.
 
-AARM Reason: We don't want to create "holey" array subtypes. By raising Program_Error, we prevent
-generic contract problems. But we also have a legality rule so when it is statically known
-(outside of a generic) we detect the problem at compile-time.]
+AARM Reason: We don't want to create "holey" array subtypes. By raising
+Program_Error, we prevent generic contract problems. But we also have a legality
+rule so when it is statically known (outside of a generic) we detect the problem
+at compile-time.]
 
 Add after 4.1.2(4):
 
 Legality Rules
 
-The discrete_range of a slice shall not statically denote a discontiguous subtype.
+The discrete_range of a slice shall not statically denote a discontiguous
+subtype.
 
 Add as the last sentence of 4.1.2(7):
 
 The evaluation of a slice raises Program_Error if any discrete_range is a
 discontiguous subtype.
 
-AARM Reason: We don't want to create "holey" slices, especially as slices can be required to
-be passed by reference (for by-reference component types). By raising Program_Error, we prevent
-generic contract problems. But we also have a legality rule so when it is statically known
-(outside of a generic) we detect the problem at compile-time.]
+AARM Reason: We don't want to create "holey" slices, especially as slices can be
+required to be passed by reference (for by-reference component types). By
+raising Program_Error, we prevent generic contract problems. But we also have a
+legality rule so when it is statically known (outside of a generic) we detect
+the problem at compile-time.]
 
 
-[Note: 4.5.2(30/2) uses "satisfies", so no changes need to be made to allow this to work in
-membership operations. Similarly, 4.6(51/2) uses "satisfies", so no wording changes are needed
-for subtype conversions.]
+[Note: 4.5.2(30/2) uses "satisfies", so no changes need to be made to allow this
+to work in membership operations. Similarly, 4.6(51/2) uses "satisfies", so no
+wording changes are needed for subtype conversions.]
 
 Modify 4.9(29):
 
-* A scalar constraint is static {if it has a list_constraint, }if it has no range_constraint,
-  or one with a static range;
+* A scalar constraint is static {if it has a list_constraint, }if it has no
+  range_constraint, or one with a static range;
 
-[Author's note: strictly speaking, we don't need to modify this sentence, as a scalar constraint
-with a list_constraint "has no range_constraint". But that's very tricky!]
+[Author's note: strictly speaking, we don't need to modify this sentence, as a
+scalar constraint with a list_constraint "has no range_constraint". But that's
+very tricky!]
 
 [For 4.9.1(1.1/2), see below; it's modified by both parts here.]
 
 Add an AARM note after 5.4(7):
 
-AARM Ramification: This implies that for a static discontiguous subtype, only the
-values belonging to that subtype should be covered. If instance, if we have:
+AARM Ramification: This implies that for a static discontiguous subtype, only
+the values belonging to that subtype should be covered. If instance, if we have:
     subtype Small_Odds is Natural when 1 | 3 | 5 | 7;
 
     case Small_Odds'(My_Func) is
@@ -211,17 +226,18 @@
 
 Add an AARM note after 5.5(9):
 
-AARM Ramification: This description implies that for loops will properly iterate over
-just the values defined by a discontiguous subtype. For instance, if we have
+AARM Ramification: This description implies that for loops will properly iterate
+over just the values defined by a discontiguous subtype. For instance, if we
+have
     subtype Small_Odds is Natural when 1 | 3 | 5 | 7;
 
     for Val in Small_Odds loop ...
 
-Val will take the values 1, 3, 5, and 7. It will *not* take the values 2, 4, and 6, even
-those are included in Small_Odds'range.
+Val will take the values 1, 3, 5, and 7. It will *not* take the values 2, 4, and
+6, even those are included in Small_Odds'range.
 
-Note that the wording requires that the values are produced in order, even if they
-are not given in order in the constraint. That's important, as:
+Note that the wording requires that the values are produced in order, even if
+they are not given in order in the constraint. That's important, as:
     subtype Small_Odds_2 is Natural when 7 | 3 | 5 | 1;
 represents the same constraint (and it will statically match Small_Odds).
 End AARM Ramification.
@@ -232,14 +248,15 @@
 
 Modify 3.3.1(12):
 
-* The implicit initial (and only) value for each discriminant of a constrained discriminanted
-  subtype is determined by the subtype. {If the discriminant constraint defines a range or
-  subtype for the value of the discriminant, the lower bound of the range or subtype is used
-  as the initial value.}
-
-AARM Reason: A discriminant constraint that defines a range or list of acceptable discriminant
-values means that any value in the range or list is acceptable for that discriminant. We select
-the lower bound in order that programs are portable (although depending on that is dubious).
+* The implicit initial (and only) value for each discriminant of a constrained
+  discriminanted subtype is determined by the subtype. {If the discriminant
+  constraint defines a range or subtype for the value of the discriminant, the
+  lower bound of the range or subtype is used as the initial value.}
+
+AARM Reason: A discriminant constraint that defines a range or list of
+acceptable discriminant values means that any value in the range or list is
+acceptable for that discriminant. We select the lower bound in order that
+programs are portable (although depending on that is dubious).
 
 Replace 3.7.1(3) by:
 
@@ -249,58 +266,62 @@
    discriminant_value ::= expression | discrete_range
 
 [Editor's note: discrete_range includes subtype_indication, so it includes list
-constraints (which aren't a range, but changing the name of the non-terminal would
-be rather disruptive).]
+constraints (which aren't a range, but changing the name of the non-terminal
+would be rather disruptive).]
 
 Modify 3.7.1(6):
 
-The expected type for the expression {or discrete_range} in a discriminant_association
-is that of the associated discriminant(s).
+The expected type for the expression {or discrete_range} in a
+discriminant_association is that of the associated discriminant(s).
 
 Modify 3.7.1(8):
 
-...A discriminant_constraint shall provide exactly one value {or subtype} for each
-discriminant of the subtype being considered.
+...A discriminant_constraint shall provide exactly one value {or subtype} for
+each discriminant of the subtype being considered.
 
 Replace 3.7.1(10) with:
 
-A discriminant_constraint is *compatible* with an unconstrained discriminanted subtype if:
+A discriminant_constraint is *compatible* with an unconstrained discriminanted
+subtype if:
 
-* the value for each discriminant given by an expression belongs to the subtype of the corresponding
-  discriminant; and
-* the constraint of the subtype for each discriminant given by a discrete_range is compatible with
-  the subtype of the corresponding discriminant.
-
-[Editor's note: Compatibility is only defined for constraints and ranges; we really want
-compatibility of subtypes here. Maybe there is a better way to write this, but there are really
-4 cases to worry about: subtype with range constraint, subtype with list constraint, subtype_mark
-alone, and range alone.]
+* the value for each discriminant given by an expression belongs to the subtype
+  of the corresponding discriminant; and
+* the constraint of the subtype for each discriminant given by a discrete_range
+  is compatible with the subtype of the corresponding discriminant.
+
+[Editor's note: Compatibility is only defined for constraints and ranges; we
+really want compatibility of subtypes here. Maybe there is a better way to write
+this, but there are really 4 cases to worry about: subtype with range
+constraint, subtype with list constraint, subtype_mark alone, and range alone.]
 
 Replace 3.7.1(11) with
 
 A composite value satisfies a discriminant_constraint if and only if:
-* for each discriminant given by an expression in the discriminant_constraint, the discriminant
-  value has the value imposed by the discriminant constraint; and
-* for each discriminant given by a discrete_range in the discrminant_constraint, the discriminant
-  value belongs to the subtype or range imposed by the discriminant constraint.
+* for each discriminant given by an expression in the discriminant_constraint,
+  the discriminant value has the value imposed by the discriminant constraint;
+  and
+* for each discriminant given by a discrete_range in the discrminant_constraint,
+  the discriminant value belongs to the subtype or range imposed by the
+  discriminant constraint.
 
 Modify 3.7.1(12):
 
-For the elaboration of a discriminant_constraint, the expressions {and discrete_ranges} in the
-discriminant_associations are evaluated in an arbitrary order and converted to the type of the
-associated discriminant (which might raise Constraint_Error  see 4.6); the expression of a
-named association is evaluated (and converted) once for each associated discriminant. The
-result of each evaluation and conversion is the value{, range, or subtype} imposed by the
-constraint for the associated discriminant. 
-
-[Editor's note: Although I find it weird, the "converted to the type of the discriminant" wording
-is used for discrete_choices in aggregates, from which discrete_ranges come. So I used the same
-wording here.]
+For the elaboration of a discriminant_constraint, the expressions {and
+discrete_ranges} in the discriminant_associations are evaluated in an arbitrary
+order and converted to the type of the associated discriminant (which might
+raise Constraint_Error  see 4.6); the expression of a named association is
+evaluated (and converted) once for each associated discriminant. The result of
+each evaluation and conversion is the value{, range, or subtype} imposed by the
+constraint for the associated discriminant.
+
+[Editor's note: Although I find it weird, the "converted to the type of the
+discriminant" wording is used for discrete_choices in aggregates, from which
+discrete_ranges come. So I used the same wording here.]
 
 Modify 4.9(31):
 
-* A discriminant constraint is static if each expression {or discrete_range} of the constraint
-  is static, and the subtype of each discriminant is static.
+* A discriminant constraint is static if each expression {or discrete_range} of
+  the constraint is static, and the subtype of each discriminant is static.
 
 ---
 
@@ -327,68 +348,133 @@
    range 1 .. 4 matches when 1 | 2 | 3 | 4 as well as when 4 | 1 .. 2 | 3.
 
 AARM Reason:
-   The rules for discriminant constraints are complex so that appropriate matching
-   can be applied to discrete_ranges. The rules imply that a value and range
-   with a single value do not match. For example:
+   The rules for discriminant constraints are complex so that appropriate
+   matching can be applied to discrete_ranges. The rules imply that a value and
+   range with a single value do not match. For example:
        Rec(2) does not match Rec(2..2).
 
-[Editor's note: I suppose we could have allowed this case, but it would have made
-the rules even more complicated.]
+[Editor's note: I suppose we could have allowed this case, but it would have
+made the rules even more complicated.]
 
 !discussion
 
-If adopted, this proposal would replace AI05-0158-1, as the subtype_indications proposed
-here could be used in membership operations. Having two nearly identical syntaxes in an
-operation would be horrible, given that they would have different rules.
+If adopted, this proposal would replace AI05-0158-1, as the subtype_indications
+proposed here could be used in membership operations. Having two nearly
+identical syntaxes in an operation would be horrible, given that they would have
+different rules.
 
 ---
 
-We make the use of discontiguous subtypes as array indicies illegal/raise Program_Error.
-It was briefly thought that we could use techniques similar to those used for holey enumeration
-types to implement them, but that is not true. Sliding would also be problematic, as well as
-holey by-reference slices (as mentioned in the AARM note above).
-
-We raise Program_Error to avoid generic contract problems. An alternative approach would
-be to add an indication that discontiguous subtypes are OK to discrete and integer formal
-subtypes. Something like:
-    type Fooey is range <> when <>;
-would work.
+An appealing alternative approach would have been to extend range_constraints to
+take a discrete_choice_list rather than a range, and then apply the array
+aggregate staticness rules to them: there can only be a single dynamic choice
+that has to stand alone.
+
+Unfortunately, that idea would make the grammar for discrete_choice_list
+ambiguous. For instance:
+
+    when Natural range 1 .. 10 | 12 | 14 =>
 
-Then, discontiguous subtypes would not be allowed to match the existing generic discrete and
-integer formals, while array operations would be illegal for the new formal types.
+Is this a single range_constraint with a discontiguous subtype, or a
+range_constraint and two choices? One could arbitrarily make this just a
+subtype_indication, but that would be subtly incompatible:
 
-This seems like killing an ant with a bazooka to the author (a lot of complication for something
-simple) and it also would reduce the usefulness of many existing generics. For instance,
-Ada.Text_IO.Integer_IO could not be instantiated with a discontiguous subtype. Obviously,
-this could be fixed for language-defined generics, but the majority of user-defined generics
-would not allow discontiguous subtypes (whether it matters or not).
+       when Natural range 1 .. 10 | (-1) =>
 
-The author believes the Program_Error solution to be less disruptive; moreover, most compilers
-could give a warning should the bad situation actually occur in an instance.
+would be illegal if this is treated as a single subtype indication (-1 is not in
+Natural), but could be legal if treated as a choice_list.
 
+Thus we need a different keyword to introduce a list_constraint in order to
+avoid this incompatibilty. We then require all list constraints to be static, as
+there isn't enough value to dynamic ones (and having fully dynamic ones would
+make implementing looping, the 'First and 'Last attributes into a nightmare).
+
 ---
+
+We make the use of discontiguous subtypes as array indicies illegal/raise
+Program_Error. It was briefly thought that we could use techniques similar to
+those used for holey enumeration types to implement them, but that is not true.
+Sliding would also be problematic, as well as holey by-reference slices (as
+mentioned in the AARM note above).
+
+We raise Program_Error to avoid generic contract problems. An alternative
+approach would be to add an indication that discontiguous subtypes are OK to
+discrete and integer formal subtypes. Something like:
+    type Fooey is range <> when <>;
+would work.
 
-An alternative semantics considered for extended discriminant constraints was for constraints
-with subtypes to be "partial constraints". A partial constraint would not make the subtype
-definite. However, that leads to additional complications not found in Ada 2005: constrained,
-indefinite subtypes. (Well, at least if you don't believe AI05-0057-1.)
-
-Since the model is that a constraint containing a subtype allows one of a set of discriminants,
-it makes sense that when an object is created using that constraint, a random value of the
-set is used to set the discriminants. We arbitrarily choose the first value simply so that
-the value chosen is the same on all compilers. This avoids the complications of new kinds
-of constraints (which would quickly spread to new kinds of generic matching rules, etc.).
+Then, discontiguous subtypes would not be allowed to match the existing generic
+discrete and integer formals, while array operations would be illegal for the
+new formal types.
+
+This seems like killing an ant with a bazooka to the author (a lot of
+complication for something simple) and it also would reduce the usefulness of
+many existing generics. For instance, Ada.Text_IO.Integer_IO could not be
+instantiated with a discontiguous subtype. Obviously, this could be fixed for
+language-defined generics, but the majority of user-defined generics would not
+allow discontiguous subtypes without modification (whether it matters or not).
+
+The author believes the Program_Error solution to be less disruptive; moreover,
+most compilers could give a warning should the bad situation actually occur in
+an instance.
 
 ---
 
-We don't allow subtypes to specify discriminant values for discriminants that have an
-access type because there would be no obvious value to use for the discriminant if the
-constraint was used to declare an object. We could allow that if we had used the
-partial constraint model instead, but that would also mean that we couldn't use
-discrete_range in the syntax.
+An alternative semantics considered for extended discriminant constraints was
+for constraints with subtypes to be "partial constraints". A partial constraint
+would not make the subtype definite. However, that leads to additional
+complications not found in Ada 2005: constrained, indefinite subtypes. (Well, at
+least if you don't believe AI05-0057-1.)
+
+Since the model is that a discriminant constraint containing a subtype allows
+one of a set of discriminants, it makes sense that when an object is created
+using that constraint, a random value of the set is used to set the
+discriminants. We arbitrarily choose the first value simply so that the value
+chosen is the same on all compilers. This avoids the complications of new kinds
+of constraints (which would quickly spread to new kinds of generic matching
+rules, etc.).
 
 ---
 
+We don't allow subtypes to specify discriminant values for discriminants that
+have an access type because there would be no obvious value to use for the
+discriminant if the constraint was used to declare an object. We could allow
+that if we had used the partial constraint model instead, but that would also
+mean that we couldn't use discrete_range in the syntax.
+
+
+!example
+
+In a compiler familar to the author, type Symbol_Ptr references a symbol
+table entry. Most routines that take a symbol table entry only allow
+certain kinds of entry. It would be valuable to be able to specify
+those kinds of entry as part of the profile of the routine.
+
+A simplified example:
+
+    type Entity_Kind is (Proc, Func, A_Type, A_Subtype, A_Package, An_Entry);
+
+    type Symbol_Record (Entity : Entity_Kind) is record ...
+
+    type Symbol_Ptr is access all Symbol_Record;
+
+    subtype Type_Symbol_Ptr is not null Symbol_Ptr (A_Type);
+    subtype Callable_Symbol_Ptr is
+       not null Symbol_Ptr (Entity_Kind when Proc | Func | An_Entry);
+
+    function Type_Size (A_Type : Type_Symbol_Ptr) return Size_Type;
+
+    procedure Generate_Call_Parameters (Callee : Callable_Symbol_Ptr; ...);
+
+
+Now, a call to Type_Size or Generate_Call_Parameters with a pointer to the wrong
+kind of symbol record will be detected at the call site rather than at some
+later point. The call site is closer to the source of the error; in addition, it
+is possible that the compiler can prove that the predicate will succeed and be
+able to remove the check altogether. That can't happen for a check inside of a
+subprogram.
+
+
 --!corrigendum 3.2.2(7)
 
 !ACATS test
@@ -399,5 +485,330 @@
 
 [Editor's note: Much of the mail that inspired these ideas can be found
 in AI05-0153-1 - June 19-23, 2009.]
+
+****************************************************************
+
+From: Tucker Taft
+Date: Wednesday, June 24, 2009  8:17 PM
+
+I think I am leaning Randy's way on this for scalar types, allowing sequences
+rather than simple ranges. I'll admit I hate the idea of using them in array
+indices, and I would hope we could disallow using non-static sequences for array
+index types, though there are generic contract model issues.  Perhaps we could
+solve this by saying that you can only use static sequences when defining a
+subtype, but possibly allow non-static sequences in some other contexts, such as
+memberships and for-loops.
+
+This has some vague symmetry with the rules for named array aggregates, where
+the choices all have to be static, unless there is exactly one choice consisting
+of one range, in which case it can be dynamic.  So we are saying that in various
+contexts, you can either use a single range, which can be dynamic, or you can
+use a static discontiguous sequence of values.  You can apply a non-static range
+on top of a static discontiguous sequence of values, but I guess that is no
+worse that having a dynamic subrange of a holey enumeration type.
+
+This doesn't really address the partially-constrained discriminated type issue.
+In that case, using a "predicate" actually seems better, since the type remains
+unconstrained in most ways, but there is a restriction on the discriminants.
+
+For array types, I'll tell you one thing I would love is a partially constrained
+array type, where I could specify the low bound while letting the high bound
+vary. But that is probably better handled with some kind of syntax like:
+
+     type Nice_Array is array(Positive range 1..<>)
+       of Element;
+
+or
+
+     subtype Nice_String is String(1..<>);
+
+Using a predicate could work:
+
+     subtype Nice_String is String
+       with Predicate => Nice_String'First = 1;
+
+but that would not be as easily recognizable by the compiler, and would probably
+not do the right thing with respect to "sliding" where you would clearly like
+parameters to "slide" so that their low bound was one, rather than failing if
+the actual'First wasn't one.
+
+Similarly, for partially constrained discriminants, the general-purpose
+"Predicate" idea might be overkill, but we would have to invent the notion of a
+partially-constrained discriminated type.  E.g.:
+
+    type Text(Max_Length : Positive) is ...
+
+    subtype Shorter_Text is Text(Max_Length in 1..10);
+
+or something like that, as opposed to:
+
+    subtype Shorter_Text is Text
+      with Predicate => Shorter_Text.Max_Length in 1..10;
+
+So it seems that two separate AIs, one for discontiguous scalar subtypes, and
+the other for partially-constrained composite types, might make sense.
+
+****************************************************************
+
+From: Steve Baird
+Date: Wednesday, June 24, 2009  8:32 PM
+
+This is sounding better and better.
+Perhaps the whole "arbitrary predicate" idea was overkill.
+These new scalars and partially constrained discriminated could play well
+together. We have a variant record with a component that only exists if the
+discriminant belongs to some noncontiguous set of discriminant values. It would
+be natural to want to define a subtype of the discriminated type that is
+constrained to that set of discriminant values. To accomplish this, we declare
+the appropriate scalar subtype and then use that in declaring the desired
+subtype of the discriminated type. We can eliminate all the generic contract
+model issues (I think) and the restrictions on array indexing, for loops, and
+(of course) entry families by following the holey enumeration type model.
+
+****************************************************************
+
+From: Randy Brukardt
+Date: Wednesday, June 24, 2009  8:40 PM
+
+> I think I am leaning Randy's way on this for scalar types, allowing
+> sequences rather than simple ranges.
+> I'll admit I hate the idea of using them in array indices, and I would
+> hope we could disallow using non-static sequences for array index
+> types, though there are generic contract model issues.  Perhaps we
+> could solve this by saying that you can only use static sequences when
+> defining a subtype, but possibly allow non-static sequences in some
+> other contexts, such as memberships and for-loops.
+
+That's essentially what I was thinking. Static discontiguous sequences are not
+too awful to implement (they're pretty close to holey enumeration types,
+although as I previously noted, the implementation scheme used by Janus/Ada for
+those won't work, at least without a lot of adjustment), dynamic ones are not so
+obvious.
+
+> This has some vague symmetry with the rules for named array
+> aggregates, where the choices all have to be static, unless there is
+> exactly one choice consisting of one range, in which case it can be
+> dynamic.  So we are saying that in various contexts, you can either
+> use a single range, which can be dynamic, or you can use a static
+> discontiguous sequence of values.  You can apply a non-static range on
+> top of a static discontiguous sequence of values, but I guess that is
+> no worse that having a dynamic subrange of a holey enumeration type.
+
+Yes, I think this is correct.
+
+> This doesn't really address the partially-constrained discriminated
+> type issue.  In that case, using a "predicate"
+> actually seems better, since the type remains unconstrained in most
+> ways, but there is a restriction on the discriminants.
+
+Right, so long as the predicate only can read the bounds/discriminants and
+static stuff and not arbitrary other junk.
+
+> For array types, I'll tell you one thing I would love is a partially
+> constrained array type, where I could specify the low bound while
+> letting the high bound vary.
+> But that is probably better handled with some kind of syntax like:
+>
+>      type Nice_Array is array(Positive range 1..<>)
+>        of Element;
+>
+> or
+>
+>      subtype Nice_String is String(1..<>);
+>
+> Using a predicate could work:
+>
+>      subtype Nice_String is String
+>        with Predicate => Nice_String'First = 1;
+>
+> but that would not be as easily recognizable by the compiler, and
+> would probably not do the right thing with respect to "sliding" where
+> you would clearly like parameters to "slide"
+> so that their low bound was one, rather than failing if the
+> actual'First wasn't one.
+
+Right. I was thinking about this, but of course nobody was very excited about
+partially constrained types in the past. (I suppose if we make that a
+first-class language concept, then the S'Class controversy can be put to rest,
+as the implementation and semantic objection would disappear. I'm not sure that
+is an advantage or disadvantage. :-)
+
+> Similarly, for partially constrained discriminants, the
+> general-purpose "Predicate" idea might be overkill, but we would have
+> to invent the notion of a partially-constrained discriminated type.
+> E.g.:
+>
+>     type Text(Max_Length : Positive) is ...
+>
+>     subtype Shorter_Text is Text(Max_Length in 1..10);
+>
+> or something like that, as opposed to:
+>
+>     subtype Shorter_Text is Text
+>       with Predicate => Shorter_Text.Max_Length in 1..10;
+
+I'm not as sure about this one, since we would often want to get discontiguous
+sets of enumerations involved. For instance, the motivating example (in the
+original AC-157, at least):
+
+      subtype Callable_Symbol is Symbol_Ptr
+         with Predicate => Callable_Symbol.Selector in (PROC | FUNC | INST_PROC | INST_FUNC | AN_ENTRY);
+
+vs.
+
+      subtype Callable_Symbol is Symbol_Ptr (Selector in (PROC | FUNC | INST_PROC | INST_FUNC | AN_ENTRY));
+
+[Symbol_Ptr is an access to unconstrained record, of course.]
+
+I guess both work, presuming that the discontiguous sequence is allowed here.
+
+> So it seems that two separate AIs, one for discontiguous scalar
+> subtypes, and the other for partially-constrained composite types,
+> might make sense.
+
+Yup. Just like I've been saying all day. ;-)
+
+****************************************************************
+
+From: Tucker Taft
+Date: Thursday, June 25, 2009  6:50 AM
+
+I had some nasty thoughts about using discontiguous subtypes as array indices,
+and concluded it really isn't worth the trouble.  In particular, slicing and
+sliding of such arrays would be really nasty. The hoped-for equivalence with
+holey enumeration types doesn't really work, since these are *sub*types, and so
+you would expect to be able to have an unconstrained array type, and then be
+able to declare objects of the type with different discontiguous subtypes as
+bounds, or expect sliding to work between such beasts.
+
+The real point of these discontiguous subtypes is to use them as choices in case
+statements, and that leads to a desire to use them as parameter and result
+subtypes, and local variable subtypes, and in membership tests and
+qualification.  But I really see *no* need to use them as array indices.
+Furthermore, because they would be non-static if passed as a formal scalar type,
+they would lose their value in case statements, and hence I see little need to
+pass them to a generic.  I also think we should disallow "'Range" on them,
+because it is too confusing to decide whether Discontig_Subt'Range means the
+discontiguous range of the subtype, or the contiguous (and probably useless)
+range D_S'First .. D_S'Last.
+
+So after thinking these could be used as "first class" subtypes, I now think we
+should relegate them to second class status, and in various places require
+*contiguous* subtypes.  In particular, we should require contiguous subtypes in
+index subtypes and index constraints, before 'Range, and as an actual for a
+formal scalar subtype.
+
+I realize making them second class makes the proposal less appealing, but in
+thinking about how to support their full generality in index subtypes and index
+constraints, I see a truly nasty amount of stupid work ahead, with little or no
+benefit.  Disallowing them in generics also is helpful, as it means shared
+generics don't need some kind of complicated descriptor just for discontiguous
+subtypes.
+
+I suppose we could invent a syntax for potentially discontiguous formal scalar
+subtypes, such as:
+
+     type T is range (<>|<>);
+or
+     type T is (<>|<>);
+
+but this seems to be pretty bad on the cost/benefit ratio scale.
+
+I still think they are useful as choices in case statements (and variant
+records), and in the other places mentioned (membership, qualification,
+profiles, variables, even loops), but allowing them as index
+subtypes/constraints, generic actuals, and before 'Range seems bad news and
+definitely more trouble than they are worth.
+
+****************************************************************
+
+From: Steve Baird
+Date: Thursday, June 25, 2009  8:59 AM
+
+> I had some nasty thoughts about using discontiguous subtypes as array
+> indices, and concluded it really isn't worth the trouble.  In
+> particular, slicing and sliding of such arrays would be really nasty.
+> The hoped-for equivalence with holey enumeration types doesn't really
+> work, since these are *sub*types, and so you would expect to be able
+> to have an unconstrained array type, and then be able to declare
+> objects of the type with different discontiguous subtypes as bounds,
+> or expect sliding to work between such beasts.
+
+You're right, of course. I was thinking these had only the same implementation
+issues as arrays indexed by holey enumeration types, but I was confused.
+
+> The real point of these discontiguous subtypes is to use them as
+> choices in case statements, and that leads to a desire to use them as
+> parameter and result subtypes, and local variable subtypes, and in
+> membership tests and qualification.  But I really see *no* need to use
+> them as array indices.  Furthermore, because they would be non-static
+> if passed as a formal scalar type, they would lose their value in case
+> statements, and hence I see little need to pass them to a generic.  I
+> also think we should disallow "'Range" on them, because it is too
+> confusing to decide whether Discontig_Subt'Range means the
+> discontiguous range of the subtype, or the contiguous (and probably
+> useless) range D_S'First .. D_S'Last.
+>
+> So after thinking these could be used as "first class"
+> subtypes, I now think we should relegate them to second class status,
+> and in various places require *contiguous* subtypes.  In particular,
+> we should require contiguous subtypes in index subtypes and index
+> constraints, before 'Range, and as an actual for a formal scalar
+> subtype.
+>
+
+And for a for-loop? I don't feel strongly about this one, but it's not hard to
+implement.
+
+As I mentioned earlier, one place I do want to be able to use these guys is in
+something like (syntax tentative):
+
+     type Enum is (Aa, Bb, Cc, Dd, Ee, Ff);
+
+     subtype Discontig is Enum in Aa .. Bb | Ee;
+
+     type Variant_Record (Discrim : Enum) is
+        record
+           case Discrim is
+               when Discontig => Foo : Integer;
+               when others => null;
+           end case;
+        end record;
+
+     subtype Has_Foo is Variant_Record (Discontig); or perhaps
+     subtype Has_Foo is Variant_Record
+       with Predicate Has_Foo.Discrim in Discontig;
+
+This depends on the other half of this AI (or the other AI, if we view this one
+as already having been split into two AIs).
+
+> I realize making them second class makes the proposal less appealing,
+> but in thinking about how to support their full generality in index
+> subtypes and index constraints, I see a truly nasty amount of stupid
+> work ahead, with little or no benefit.  Disallowing them in generics
+> also is helpful, as it means shared generics don't need some kind of
+> complicated descriptor just for discontiguous subtypes.
+
+You've convinced me.
+
+> I suppose we could invent a syntax for potentially discontiguous
+> formal scalar subtypes, such as:
+>
+>     type T is range (<>|<>);
+> or
+>     type T is (<>|<>);
+>
+> but this seems to be pretty bad on the cost/benefit ratio scale.
+
+Agreed. And we can always add this later in the unlikely event that we decide
+that this is wanted.
+
+> I still think they are useful as choices in case statements (and
+> variant records), and in the other places mentioned (membership,
+> qualification, profiles, variables, even loops), but allowing them as
+> index subtypes/constraints, generic actuals, and before 'Range seems
+> bad news and definitely more trouble than they are worth.
+
+And I had my heart set on using discontiguous entry families ...
 
 ****************************************************************

Questions? Ask the ACAA Technical Agent