!standard 4.4 (3) 09-06-07 AI05-0158-1/01 !standard 4.5.2(3) !standard 4.5.2(30/2) !class Amendment 09-06-07 !status work item 09-06-07 !status received 09-03-30 !priority Low !difficulty Medium !subject Generalizing membership tests !summary Extend the syntax of membership tests to simplify complex conditions that can be expressed as membership in a subset of values of any type. !problem Conditions of the form (X = A) or else (X = B) or else (X = C) where A, B, C are of some arbitrary type are common, and will be more frequent when pre- and post-conditions become widely used. If the values of A, B,and C are contiguous values of some discrete type, the expression can be written as a membership operation: (X in A..C) . Otherwise this syntactic shortcut is not available. We propose a simple extension of the syntax of membership operations, so that the right operand can specify a subset of values of some type. !proposal Extend the syntax of memberships as shown in the wording. !wording Modify 4.4(3) as follows: relation ::= simple_expression [not] in choice_list choice_list ::= choice {'|' choice} choice ::= simple_expression | range | subtype_mark [Editor's comment: This grammar is ambiguous if the expression is used in a discrete_choice_list (that is, in a variant part, case statement, or array aggregate). See the !discussion section.] Add after 4.5.2(3): (Name Resolution Rules) If the choice_list in a membership operation has more that one choice, then all choices must have a single common type, which is the tested type of the operation. Add somewhere in 4.5.2(28-31): (Dynamic Semantics) The left operand is elaborated first. If the choice_list has more that one choice, the operation is equivalent to a short-circuit sequence of tests : if a choice is a simple expression the corresponding test is an equality operation, otherwise it is a membership test whose right operand is the corresponding range or subtype_mark. [Editor's comment: The first sentence contradicts 4.5.2(27). Is that really what we want? We ought to reword this to fit in with the existing wording.] !discussion The new syntax introduces an ambiguity in case statements whose expression is boolean: X : Boolean := .. case X is when Y in 1..10 | 20 => -- ambiguous: -- could be (Y in 1..10) | 20 -- which is otherwise type-incorrect The ambiguity only arises if the case expression is boolean and if the left operand and expressions are all static, which seems extremely rare. The simplest is to state that a membership operation with multiple expressions that appears in a case alternative must be parenthesized. [Editor's comment: The same surely is true of variant parts, and is *almost* true of array aggregates (there is no requirement for staticness there). Also note that you can write legal such expressions, but they would only happen in ACATS tests: when X in True | False => (!)] !example !ACATS test Add an ACATS test for this new feature. !appendix ****************************************************************