Version 1.7 of ai12s/ai12-0039-1.txt

Unformatted version of ai12s/ai12-0039-1.txt version 1.7
Other versions for file ai12s/ai12-0039-1.txt

!standard 4.4(3/3)          13-05-08 AI12-0039-1/03
!standard 4.4(3.2/3)
!standard 4.5.2(3.1/3)
!standard 4.5.2(4)
!standard 4.5.2(4.1/3)
!standard 4.5.2(27/3)
!standard 4.5.2(27.1/3)
!standard 4.5.2(28.1/3)
!standard 4.5.2(28.2/3)
!standard 4.5.2(29/3)
!standard 4.5.2(30/3)
!standard 4.5.2(30.1/3)
!standard 4.5.2(30.2/3)
!standard 4.5.2(30.3/3)
!standard 4.9(11/3)
!standard 4.9(32.6/3)
!standard 8.6(27.1/3)
!standard 3.2.4(17/3)
!class binding interpretation 12-11-29
!status Corrigendum 2014 12-12-17
!status WG9 Approved 13-06-14
!status ARG Approved 8-0-2 12-12-06
!status work item 12-11-29
!status received 12-10-09
!priority High
!difficulty Easy
!subject Ambiguity in syntax for membership expression removed
!summary
The choices of a membership are syntactically simple_expressions, not choice_expressions.
!question
It appears that the Ada 2012 syntax for membership expressions introduces ambiguities.
Assume A, B, C, and D are all objects of type Boolean.
Consider
A in B and C
This could be interpreted as equivalent to either of these valid Ada expressions:
(A in B) and C --or as A in (B and C)
Similarly:
A in B in C | D can be interpreted as
A in (B in C) | D --or as A in (B in C | D)
And:
A in B | C and D can be interpreted as
(A in B | C) and D --or as A in B | (C and D)
Should the syntax be corrected to eliminate these ambiguities? (Yes.)
!recommendation
(See summary.)
!wording
Replace the last line of 4.4(3) with:
| tested_simple_expression [not] in membership_choice_list
Replace 4.4(3.2/3) with:
membership_choice ::= *choice_*simple_expression | range | subtype_mark
[Note: The change here is to replace "choice_expression" with "choice_simple_expression"; it would be ambiguous to use the usual insertion and deletion marks in syntax, so this was not done here.]
In 4.5.2, paragraphs 3.1/3 [only the two uses], 3.b/2, 4, 27/3, 27.1/3, 28.1/3, 28.2/3, 29/3, 30/3, 30.a, 30.1/2, 30.2/2, 30.3/2, and 32.a/3, in 4.9(11/3),
in 3.2.4(17/3), and in 8.6(27.1/3):
replace "simple_expression" with "tested_simple_expression".
In 4.5.2, paragraphs 3.1/3, 4.1/3, 28.1/3, in 4.9(11/3), and in 4.9(32.6/3): replace "choice_expression" with "choice_simple_expression".
[Editor's note: There are a few cases where we don't have to use the new prefixes, especially for the latter cases (where we often say "of a membership_choice") but it's going to be clearer to just use them globally.]
In AARM 3.9.2(9.b/2), "expression" probably should be "tested_simple_expression", although this isn't absolutely required.
[Editor's note: I searched for "membership", "choice_expression", and "simple_expression" everywhere in the Standard (and AARM), and the above are the changes that I found.]
!discussion
The basic intent was that the choice of a membership was syntactically equivalent to the other uses of a choice (such as in a case statement). Choice_expression was introduced to minimize the incompatibility with existing choices in case statements. Unfortunately, we failed to notice that doing so made the grammar ambiguous.
Clearly, the constituents of a membership choice either have to have higher precedence than a membership or have to be enclosed in parentheses. If a membership or logical operator is used in a membership choice, it has to be parenthesized.
This is most easily accomplished by making a membership choice a simple expression; this gives the proper precedence.
It is annoying that choices for memberships and case statements are subtly different. Had this been a concern in 1994, probably choices would never have been changed from simple_expression (in Ada 83) to expression (in Ada 95) to choice_expression (in Ada 2012). But today, minimizing compatibility issues with Ada 95 has to be more important than having everything exactly the same.
Note that this change has no effect the interpretation of on any syntax or construct that existed in Ada 2005 or before; it only could change the interpretation of new Ada 2012 expressions (of which there are hopefully very few taking advantage of this ambiguity).
Unfortunately, changing the syntax this way makes all of the rules that talk about "the simple_expression" and "a choice_expression" in 4.5.2 ambiguous. As such, we have to give these syntax items prefixes to eliminate any confusion. Thus we talk about "tested_simple_expression" and "choice_simple_expression".
!corrigendum 3.2.4(17/3)
Replace the paragraph:
by:
!corrigendum 4.4(3/3)
Replace the paragraph:
relation ::= simple_expression [relational_operator simple_expression] | simple_expression [not] in membership_choice_list
by:
relation ::= simple_expression [relational_operator simple_expression] | tested_simple_expression [not] in membership_choice_list
!corrigendum 4.4(3.2/3)
Replace the paragraph:
membership_choice ::= choice_expression | range | subtype_mark
by:
membership_choice ::= choice_simple_expression | range | subtype_mark
!corrigendum 4.5.2(3.1/3)
Replace the paragraph:
If the tested type is tagged, then the simple_expression shall resolve to be of a type that is convertible (see 4.6) to the tested type; if untagged, the expected type for the simple_expression is the tested type. The expected type of a choice_expression in a membership_choice, and of a simple_expression of a range in a membership_choice, is the tested type of the membership operation.
by:
If the tested type is tagged, then the tested_simple_expression shall resolve to be of a type that is convertible (see 4.6) to the tested type; if untagged, the expected type for the tested_simple_expression is the tested type. The expected type of a choice_simple_expression in a membership_choice, and of a simple_expression of a range in a membership_choice, is the tested type of the membership operation.
!corrigendum 4.5.2(4)
Replace the paragraph:
For a membership test, if the simple_expression is of a tagged class-wide type, then the tested type shall be (visibly) tagged.
by:
For a membership test, if the tested_simple_expression is of a tagged class-wide type, then the tested type shall be (visibly) tagged.
!corrigendum 4.5.2(4.1/3)
Replace the paragraph:
If a membership test includes one or more choice_expressions and the tested type of the membership test is limited, then the tested type of the membership test shall have a visible primitive equality operator.
by:
If a membership test includes one or more choice_simple_expressions and the tested type of the membership test is limited, then the tested type of the membership test shall have a visible primitive equality operator.
!corrigendum 4.5.2(27/3)
Replace the paragraph:
For the evaluation of a membership test using in whose membership_choice_list has a single membership_choice, the simple_expression and the membership_choice are evaluated in an arbitrary order; the result is the result of the individual membership test for the membership_choice.
by:
For the evaluation of a membership test using in whose membership_choice_list has a single membership_choice, the tested_simple_expression and the membership_choice are evaluated in an arbitrary order; the result is the result of the individual membership test for the membership_choice.
!corrigendum 4.5.2(27.1/3)
Replace the paragraph:
For the evaluation of a membership test using in whose membership_choice_list has more than one membership_choice, the simple_expression of the membership test is evaluated first and the result of the operation is equivalent to that of a sequence consisting of an individual membership test on each membership_choice combined with the short-circuit control form or else.
by:
For the evaluation of a membership test using in whose membership_choice_list has more than one membership_choice, the tested_simple_expression of the membership test is evaluated first and the result of the operation is equivalent to that of a sequence consisting of an individual membership test on each membership_choice combined with the short-circuit control form or else.
!corrigendum 4.5.2(28.1/3)
Replace the paragraph:
by:
!corrigendum 4.5.2(28.2/3)
Replace the paragraph:
by:
!corrigendum 4.5.2(29/3)
Replace the paragraph:
by:
!corrigendum 4.5.2(30/3)
Replace the paragraph:
by:
!corrigendum 4.5.2(30.1/2)
Replace the paragraph:
if the type of the simple_expression is class-wide, the value has a tag that identifies a type covered by the tested type;
by:
if the type of the tested_simple_expression is class-wide, the value has a tag that identifies a type covered by the tested type;
!corrigendum 4.5.2(30.2/3)
Replace the paragraph:
by:
!corrigendum 4.5.2(30.3/3)
Replace the paragraph:
by:
!corrigendum 4.9(11/3)
Replace the paragraph:
by:
!corrigendum 4.9(32.6/3)
Replace the paragraph:
by:
!corrigendum 8.6(27.1/3)
Replace the paragraph:
Other than for the simple_expression of a membership test, if the expected type for a name or expression is not the same as the actual type of the name or expression, the actual type shall be convertible to the expected type (see 4.6); further, if the expected type is a named access-to-object type with designated type D1 and the actual type is an anonymous access-to-object type with designated type D2, then D1 shall cover D2, and the name or expression shall denote a view with an accessibility level for which the statically deeper relationship applies; in particular it shall not denote an access parameter nor a stand-alone access object.
by:
Other than for the tested_simple_expression of a membership test, if the expected type for a name or expression is not the same as the actual type of the name or expression, the actual type shall be convertible to the expected type (see 4.6); further, if the expected type is a named access-to-object type with designated type D1 and the actual type is an anonymous access-to-object type with designated type D2, then D1 shall cover D2, and the name or expression shall denote a view with an accessibility level for which the statically deeper relationship applies; in particular it shall not denote an access parameter nor a stand-alone access object.
!ACATS test
An ACATS B-Test could be created to test these rules, but we generally don't test syntax rules (and the rules given in the Ada 2012 Standard cannot be usefully implemented).
!ASIS
No ASIS impact.
!appendix

!topic Ambiguous grammar related to new membership test
!reference 4.4(2-3.2/3)
!from Adam Beneschan 12-10-09
!discussion

It appears to me that the new syntax for membership choice lists
(AI05-158) has introduced some ambiguities into the grammar.  I found
this out while looking into a comp.lang.ada post from Maxim Reznik
(https://groups.google.com/forum/?hl=en&fromgroups=#!topic/comp.lang.ada/UYjxb612B_s).

Assume A, B, C, and D are all objects of type Boolean.  Here are some
cases that I believe are ambiguous:

A in B and C [Maxim's original example] can be interpreted as
equivalent to either of these valid Ada expressions:
   (A in B) and C      --or as
   A in (B and C)

The problem is that in the second interpretation, the
membership_choice_list can be one or more membership_choices, and a
membership_choice can be a choice_expression, and a choice_expression
can be two choice_relations connected by a logical operator ("and").

A couple other examples:

A in B in C | D  can be interpreted as
   A in (B in C) | D   --or as
   A in (B in C | D)

A in B | C and D can be interpreted as
   (A in B | C) and D  --or as
   A in B | (C and D)

(Note: Although I cannot imagine ever writing a membership test with a
Boolean as the left-hand value, except in a simple case such as A in
Arr'Range where Arr is an array (Boolean range <>) of something, I
think it needs to be fixed since it's not good to have an ambiguous
grammar.)

I think the solution is probably to change

  membership_choice ::= choice_expression | range | subtype_mark

to

  membership_choice ::= simple_expression | range | subtype_mark

which means that in the new multiple-choice membership test, the
choices on the right side could not use logical or relational
operators except in parentheses.  This wouldn't introduce any
incompatibilities except with the new form of membership test; in
particular, since discrete_choice_lists would still use
choice_expressions, rather than simple_expressions, CASE statements,
variant parts, and array aggregates wouldn't be affected.  

If this change is made, then it might no longer make sense for
choice_expression and choice_relation to be defined in 4.4 since they
wouldn't be used in an expression; maybe it could be moved to 3.8.1.
But that's a less important issue.  Also, if this change is made,
some wording changes would be needed in 4.5.2, and maybe elsewhere (I
haven't checked).

****************************************************************

From: Tucker Taft
Sent: Wednesday, October 10, 2012  7:47 AM

...
> I think the solution is probably to change
>
>    membership_choice ::= choice_expression | range | subtype_mark
>
> to
>
>    membership_choice ::= simple_expression | range | subtype_mark

I agree with your analysis.

> which means that in the new multiple-choice membership test, the 
> choices on the right side could not use logical or relational 
> operators except in parentheses.  This wouldn't introduce any 
> incompatibilities except with the new form of membership test; in 
> particular, since discrete_choice_lists would still use 
> choice_expressions, rather than simple_expressions, CASE statements, 
> variant parts, and array aggregates wouldn't be affected.
>
> If this change is made, then it might no longer make sense for 
> choice_expression and choice_relation to be defined in 4.4 since they 
> wouldn't be used in an expression; maybe it could be moved to 3.8.1.
> But that's a less important issue.  Also, if this change is made, some 
> wording changes would be needed in 4.5.2, and maybe elsewhere (I 
> haven't checked).

Yes, I agree it might make sense to move choice_expression, but that is a bigger
change which at this stage is probably not worth it.

****************************************************************

Questions? Ask the ACAA Technical Agent