!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
****************************************************************