CVS difference for ai05s/ai05-0147-1.txt

Differences between 1.9 and version 1.10
Log of other versions for file ai05s/ai05-0147-1.txt

--- ai05s/ai05-0147-1.txt	2010/01/22 00:32:47	1.9
+++ ai05s/ai05-0147-1.txt	2010/02/02 04:49:31	1.10
@@ -1,5 +1,5 @@
-!standard 4.3.3(15)                                    10-01-21  AI05-0147-1/07
-!standard 4.4(7)
+!standard 4.3.3(15)                                    10-02-01  AI05-0147-1/08
+!standard 4.4(1)
 !standard 4.5.7(0)
 !standard 4.7(2)
 !standard 4.7(3)
@@ -65,13 +65,15 @@
    Precondition => (not Param_1 >= 0) or Param_2 /= ""
 but this sacrifices a lot of readability, when what is actually meant is
    Precondition => (if Param_1 >= 0 then Param_2 /= "" else True)
+or even more simply
+    Precondition => (if Param_1 >= 0 then Param_2 /= "")
+(depending on an implicit else).
 
-
 Another situation is renaming an object determined at runtime:
 
      procedure S (A, B : Some_Type) is
          Working_Object : Some_Type renames
-            (if Some_Func(A) then A else B);
+            Some_Type'(if Some_Func(A) then A else B);
      begin
          -- Use Working_Object in a large chunk of code.
      end S;
@@ -95,43 +97,14 @@
 * For a conditional_expression, the applicable index constraint for
   each *dependent_*expression is that, if any, defined for the
   conditional_expression.
+
+Modify 4.4(1):
 
-Replace 4.4(7) by:
+    In this International Standard, the term "expression" refers to a construct
+    of the syntactic category expression or of any of the [other five syntactic
+    categories defined below]{following categories: relation,
+    simple_expression, term, factor, primary, conditional_expression}.
 
-primary ::=
-   numeric_literal | null | string_literal | aggregate
- | name | allocator | (expression_within_parentheses)
-
-Add after 4.4(7):
-
-expression_within_parentheses ::=
-   expression
- | conditional_expression
-
-If an expression appears directly inside of another set of parentheses,
-an expression_within_parentheses can be used instead. Redundant[This allows
-the use of a single set of parentheses in such cases.]
-
-AARM Reason: We could have written this as a syntax rule (as we did in
-4.7, for instance), but that would have required rewriting many semantic
-rules that depend on the syntax item expression (for instance, the 3rd,
-4th, and 7th paragraphs in 4.1.1, the 7th and 8th paragraphs of 4.1.4,
-the third paragraph of 4.6, and many more).
-
-AARM Ramification: This rule applies to
-attribute_designator and range_attribute_designator (4.1.4),
-type_conversion (4.6), entry_index (9.5.2), and to single (positional)
-items in pragma (2.8), discriminant_constraint (3.7.1),
-indexed_component (4.1.1), actual_parameter_part (6.4),
-and generic_actual_part (12.3).
-
-AARM Implementation Note: In order to avoid ambiguity, and preserve the
-ability to do useful error correction, it is recommended that the grammar
-for all of the above productions be modified to reflect this rule. For the
-four productions, replacing expression with expression_within_parentheses
-in the grammar will have the correct effect; for the latter productions,
-adding a parallel singleton_list ::= ( conditional_expression ) will have
-the correct effect without adding any ambiguity.
 
 Add a new clause:
 
@@ -142,8 +115,101 @@
 conditional_expression ::= if condition then *dependent*_expression
     {elsif condition then *dependent*_expression}
     [else *dependent*_expression]
+
+condition ::= *boolean_*expression
+
+Whereever the Syntax Rules allow an expression, a conditional_expression may be
+used in place of the expression, so long as it is immediately surrounded by
+parentheses.
+
+AARM Discussion: The syntactic category conditional_expression is not explicitly
+referenced by any other BNF syntax rules. The above rule "plugs it in" to the
+rest of the grammar, by allowing conditional_expression to play the syntactic
+role of expression, except that it must be parenthesized.
+
+One of the possibilities for primary is (expression). The above rule implies
+that we can use (conditional_expression) instead, so the following are
+syntactically legal:
+
+    A := (if X then Y else Z); -- parentheses required
+    A := B + (if X then Y else Z) + C; -- parentheses required
+
+The following procedure calls are syntactically legal:
+
+    P(if X then Y else Z);
+    P((if X then Y else Z)); -- redundant parentheses
+
+    P((if X then Y else Z), Some_Other_Param);
+    P(Some_Other_Param, (if X then Y else Z));
+    P(Formal => (if X then Y else Z));
+
+whereas the following are illegal:
+
+    P(if X then Y else Z, Some_Other_Param);
+    P(Some_Other_Param, if X then Y else Z);
+    P(Formal => if X then Y else Z);
+
+because in these latter cases, the conditional_expression is not immediately
+surrounded by parentheses (which means on both sides!).
+
+The above English-language rule is equivalent to modifying the BNF as follows,
+as far as syntax goes:
+
+    expression_within_parens ::=
+      expression |
+      conditional_expression
+
+    singleton_list ::= ( conditional_expression )
+
+    primary ::=  numeric_literal | null | string_literal | aggregate |
+       name | allocator | (expression_within_parens)
+
+    pragma_argument_association_list ::=
+     (pragma_argument_association {, pragma_argument_association})
+      | singleton_list
+
+    pragma ::= Pragma identifier [pragma_argument_association_list] ;
+
+    discriminant_constraint ::=
+        (discriminant_association {, discriminant_association}) |
+        singleton_list
+
+    index_expression_list ::= (expression {, expression}) | singleton_list
+
+    indexed_component ::= prefix index_expression_list
+
+    attribute_designator ::=
+      identifier[(*static*_expression_within_parans)]
+
+    range_attribute_designator ::=
+      Range[(*static*_expression_within_parens)]
+
+    type_conversion ::=
+      subtype_mark (expression_within_parens)
+
+    qualified expression ::=
+      subtype_mark'(expression_within_parens)
+
+    actual_parameter_part ::=
+        (parameter_association {, parameter_association}) |
+        singleton_list
+
+    entry_index ::= expression_within_parens
+
+    generic_actual_part ::=
+        (generic_association {, generic_association}) |
+        singleton_list
+
+We chose not to make this modification because it is a huge change to the BNF
+grammar, and in addition would require a lot of English text that refers to
+syntactic categories to change.
+
+AARM Implementation Note: Implementers are cautioned to consider error
+detection when implementing the syntax for conditional_expressions.
+Conditional_expressions and if_statements are very similar syntactally,
+and simple mistakes can appear to change one into the other, potentially
+causing errors to be moved far away from their actual location.
 
-condition ::= Boolean_expression
 
     Name Resolution Rules
 
@@ -165,15 +231,16 @@
 (instead of a particular type), all *dependent_*expressions of the
 conditional_expression shall have the same type.
 
-If there is no "else" *dependent_*expression, all of the *dependent_*expressions of
-the conditional_expression shall be of a boolean type.
+If there is no "else" *dependent_*expression, all of the *dependent_*expressions
+of the conditional_expression shall be of a boolean type.
 
 If the expected type of a conditional_expression is a specific tagged type, all
-of the *dependent_*expressions of the conditional_expression shall be dynamically
-tagged, or none shall be dynamically tagged; the conditional_expression is
-dynamically tagged if all of the *dependent_*expressions are dynamically tagged,
-is tag-indeterminate if all of the *dependent_*expressions are tag-indeterminant,
-and is statically tagged otherwise.
+of the *dependent_*expressions of the conditional_expression shall be
+dynamically tagged, or none shall be dynamically tagged; the
+conditional_expression is dynamically tagged if all of the
+*dependent_*expressions are dynamically tagged, is tag-indeterminate if all of
+the *dependent_*expressions are tag-indeterminant, and is statically tagged
+otherwise.
 
 [Editor's note: We don't try to define the type of the conditional expression;
 it gets complex when implicit conversions are involved. There may not be a
@@ -194,16 +261,7 @@
 intact. Note that the last otherwise can be true only for a boolean
 conditional expression, as an "else" is required in all other cases.]
 
-Replace 4.7(2) by:
-
-qualified_expression ::=
-   subtype_mark'(expression_within_parentheses) | subtype_mark'aggregate
-
-In 4.7(3), modify the start of the paragraph:
 
-The *operand* (the {expression_within_parentheses}[expression], or aggregate)
-shall...
-
 Add after 4.9(12):
 
 * A conditional_expression all of whose conditions and dependent_expressions are
@@ -248,15 +306,15 @@
 In the following contexts, an expression of a limited type is not permitted
 unless it is an aggregate, a function_call, [or ]a parenthesized expression or
 qualified_expression whose operand is permitted by this rule{, or a
-conditional_expression all of whose *dependent_*expressions are permitted by this
-rule}:
+conditional_expression all of whose *dependent_*expressions are permitted by
+this rule}:
 
 
 
 !discussion
 
 The syntax of Ada requires that we require some sort of surrounding syntax to
-make a conditional expression different than a if statement. Without that
+make a conditional expression different than an if statement. Without that
 requirement, we would have code like:
 
    if if Func1 then Func2 then Proc1; end if;
@@ -7741,3 +7799,280 @@
 
 ****************************************************************
 
+From: Bob Duff
+Sent: Monday, February  1, 2010  3:22 PM
+
+Here's my homework for ai05-0147-1.
+
+The goal is to fix the syntax rules.
+My understanding is that we all agree on the rules, but we were having trouble
+expressing those rules in RM-ese.
+
+I realized we were mixing two approaches:
+
+    - Stick conditional_expression into the BNF grammar
+      where appropriate.  We don't like this because
+      it involves too much change to the RM.
+
+    - Leave the BNF grammar alone, but describe in English
+      where conditional_expression is allowed in place
+      of the syntactic category expression.  We don't
+      like this for the same reason we don't like
+      a similar ugly hack when used for pragmas.
+
+I decided to go entirely with the second approach (so there's only one "don't
+like").
+
+We had been using the first approach in primary and qualified_expression.  I got
+rid of that -- the wording below eliminates the previously-proposed changes to
+those BNF rules; that is, the BNF syntax rules for primary and
+qualified_expression remain as in Ada 2005.
+
+This has the "interesting" property that conditional_expression is not
+referenced in BNF -- only in the English syntax rule that plugs it in (allows it
+to replace expression, sometimes).
+
+Here goes:
+
+[This is version /08 of the AI - Editor.]
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, February  1, 2010  4:07 PM
+
+I think we had also talked about allowing an unparenthesized conditional
+expression immediately following "=>".  I think we certainly want that in the
+aspect specifications.
+
+****************************************************************
+
+From: Edmond Schonberg
+Sent: Monday, February  1, 2010  4:23 PM
+
+as long as it is followed by a ')',  right? This is a little harder to phrase
+properly.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Monday, February  1, 2010  4:31 PM
+
+Didn't we explicitly decide against
+this because of interactions with case
+expressions (and we wanted the same parenthesizing rules for conditional
+expressions as for case expressions)?
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, February  1, 2010  5:20 PM
+
+That's what it says in the minutes, and is surely what I understood we had
+decided. Otherwise, case expressions become ambiguous, which would not be good.
+Or we have different rules for everything (aggregates, case exprs, cond exprs,
+...), which sounds like a nightmare.
+
+****************************************************************
+
+From: Bob Duff
+Sent: Monday, February  1, 2010  3:31 PM
+
+This is mostly nitpicking.  I'd rather you review the proposed wording I sent a
+few minutes ago, if you don't have time for both.
+
+AI05-0147-1 says:
+
+> It is possible to write a Boolean expression like
+>    Precondition => (not Param_1 >= 0) or Param_2 /= ""
+> but this sacrifices a lot of readability, when what is actually meant is
+>    Precondition => (if Param_1 >= 0 then Param_2 /= "" else True)
+
+We allow "else True" to be defaulted, so this might be
+better:
+
+   Precondition => (if Param_1 >= 0 then Param_2 /= "")
+  where "else True" is implied by default.
+
+> Another situation is renaming an object determined at runtime:
+>
+>      procedure S (A, B : Some_Type) is
+>          Working_Object : Some_Type renames
+>             (if Some_Func(A) then A else B);
+>      begin
+>          -- Use Working_Object in a large chunk of code.
+>      end S;
+>
+> In Ada currently, you would have to either duplicate the working code
+> (a bad idea if it is large) or make the working code into a subprogram
+> (which adds overhead, and would complicate the use of exit and return control structures).
+
+I don't think we plan to allow that (even though it might be nice!).
+An object_renaming_decl requires a name, whereas a conditional_expression is
+merely an expression.  Nor do we intend to allow:
+
+    (if Some_Func(...) then X else Y) := Toto;
+
+Right?
+
+On the other hand, I suppose this:
+
+    (if Some_Func(...) then X else Y).all := Toto;
+                                     ^^^^ will be allowed.
+
+Note redundant "Redundant" in:
+
+> If an expression appears directly inside of another set of
+> parentheses, an expression_within_parentheses can be used instead.
+> Redundant[This allows the use of a single set of parentheses in such
+> cases.]
+
+The following strikes me as overly paternalistic:
+
+> AARM Implementation Note: In order to avoid ambiguity, and preserve
+> the ability to do useful error correction, it is recommended that the
+> grammar for all of the above productions be modified to reflect this rule. ...
+
+We don't normally presume to tell implementers how best to do syntactic error
+correction.
+
+First para of !discussion: "a if" --> "an if".
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, February  1, 2010  5:51 PM
+
+> > It is possible to write a Boolean expression like
+> >    Precondition => (not Param_1 >= 0) or Param_2 /= ""
+> > but this sacrifices a lot of readability, when what is actually meant is
+> >    Precondition => (if Param_1 >= 0 then Param_2 /= "" else True)
+>
+> We allow "else True" to be defaulted, so this might be
+> better:
+>
+>    Precondition => (if Param_1 >= 0 then Param_2 /= "") where "else
+> True" is implied by default.
+
+I wanted to be crystal-clear about the equivalence, and the defaulted "else"
+is not crystal-clear to me. Indeed, I have to look it up each time to figure out
+what it is.
+
+Perhaps the thing to do is here to give both by adding:
+
+or even more simply
+    Precondition => (if Param_1 >= 0 then Param_2 /= "")
+
+to the AI.
+
+> > Another situation is renaming an object determined at runtime:
+> >
+> >      procedure S (A, B : Some_Type) is
+> >          Working_Object : Some_Type renames
+> >             (if Some_Func(A) then A else B);
+> >      begin
+> >          -- Use Working_Object in a large chunk of code.
+> >      end S;
+> >
+> > In Ada currently, you would have to either duplicate the working
+> > code (a bad idea if it is large) or make the working code into a
+> > subprogram (which adds overhead, and would complicate the use of
+> > exit and return control structures).
+>
+> I don't think we plan to allow that (even though it might be nice!).
+> An object_renaming_decl requires a name, whereas a
+> conditional_expression is merely an expression.
+
+Oh, sorry. I should have written:
+
+          Working_Object : Some_Type renames
+             Some_Type'(if Some_Func(A) then A else B);
+
+because you can make any expression a name by qualifying it (AI05-0003-1).
+And, as Tucker pointed out, you can do that in Ada 95-speak, without
+AI05-0003-1, too:
+
+          Working_Object : Some_Type renames
+             Some_Type(Some_Type'(if Some_Func(A) then A else B));
+
+But there is a weirdness here, because the name represents a constant view (at
+least according to AI05-0003-1). So it isn't a 100% replacement for the
+renaming.
+
+One wonders if we want a rule to disallow this case (is it more confusing than
+helpful??). I think it would have to be a specific rule.
+
+> Nor do we
+> intend to allow:
+>
+>     (if Some_Func(...) then X else Y) := Toto;
+>
+> Right?
+
+     Some_Type'(if Some_Func(...) then X else Y) := Toto;
+
+is illegal because the LHS is a constant view.
+
+> On the other hand, I suppose this:
+>
+>     (if Some_Func(...) then X else Y).all := Toto;
+>                                      ^^^^ will be allowed.
+
+That won't work (the prefix is not a name), but of course:
+
+     Some_Type'(if Some_Func(...) then X else Y).all := Toto;
+
+would be legal.
+
+
+> Note redundant "Redundant" in:
+>
+> > If an expression appears directly inside of another set of
+> > parentheses, an expression_within_parentheses can be used instead.
+> > Redundant[This allows the use of a single set of parentheses in such
+> > cases.]
+
+We're started adding "Redundant" in front the square brackets, because we also
+use square brackets to mean deletion, and we've been confused on multiple
+occasions. This is text you replaced anyway, so it doesn't matter.
+
+> The following strikes me as overly paternalistic:
+>
+> > AARM Implementation Note: In order to avoid ambiguity, and preserve
+> > the ability to do useful error correction, it is recommended that
+> > the grammar for all of the above productions be modified to reflect
+> > this rule. ...
+>
+> We don't normally presume to tell implementers how best to do
+> syntactic error correction.
+
+I think this is a special case. The grammar in the standard is seriously
+ambiguous and since a reasonably easy solution is known and available, I think
+we should give it and explain why they would like to use it. That's especially
+true because my professional opinion was that it couldn't be done (I thought
+that inherent ambiguity, especially for "name", would have made it impossible).
+This is one case where I was happy to be proved wrong, and I don't want to lose
+that information as other implementers may have similar problems. (And not
+everyone one reads the AIs, or even knows what they are.)
+
+You could argue that there are existing cases like that in the Ada grammar; I
+agree with that but think they too ought to have AARM notes if the published
+grammar is problematic. Type_conversion comes to mind (this has to be treated as
+a form of name, especially as it is allowed to be *used* as a name). There are
+only a few such places in the standard; it's annoying that new Ada implementers
+are supposed to figure out these problems and solutions on their own.
+
+Anyway, there may be a better way to put this, but clearly every implementer
+will need a solution to avoid the ambiguity (unless they are using an ambiguous
+grammar parser, but that seems unlikely). So I think we ought to help. Your
+elimination of any grammar at all will make it even harder for readers to make
+sense of this. Maybe something like:
+
+AARM Implementation Note: Directly adding conditional_expression in place of
+expression causes a very ambiguous grammar. Instead, it is possible to modify
+the grammar for all of the above productions to reflect this rule.
+...
+
+or something like that.
+
+****************************************************************

Questions? Ask the ACAA Technical Agent