CVS difference for ai05s/ai05-0147-1.txt
--- ai05s/ai05-0147-1.txt 2009/10/29 08:08:09 1.4
+++ ai05s/ai05-0147-1.txt 2009/11/04 06:24:24 1.5
@@ -103,17 +103,18 @@
{elsif condition then *dependent*_expression}
[else *dependent*_expression])
+condition ::= Boolean_expression
+
Name Resolution Rules
+A condition is expected to be of any boolean type.
+
The expected type for a conditional_expression shall be a single
type. The expected type for each *dependent*_expression of a
conditional_expression shall be the type of the conditional_expression.
Redundant[The expected type for each condition is expected to be of any
boolean type (see 5.3).]
-[Editor's Note: "condition" is defined in 5.3. Should it (both syntax and
-semantics - 2 lines) be moved here to avoid the forward reference??]
-
Legality Rules
If there is no "else" dependent_expression, the type of the conditional_expression
@@ -188,9 +189,12 @@
I don't think this level of detail is common enough to add to the language, but
the rewrite of this paragraph would make it easy to add here if desired.]
+Delete 5.3(3-4) [they were moved to 4.5.7]
+
** TBD: We need wording to deal with built-in-place issues. In particular, a
conditional expression ought to work like a set of parens rather than an aggregate
-with one component: no temporary object would be created (even logically).
+with one component: no temporary object would be created (even logically). Some
+wording will be needed for this.
** TBD: We also need to deal with the case that the various results have mixed
tagged states: if one result is statically tagged and another is dynamically tagged,
@@ -198,6 +202,28 @@
something to be illegal (we wouldn't want this to be a way to avoid 3.9.2(8-9)).
[Well, I might, but that's a different issue. ;-)]
+** TBD: The name resolution rule needs to be replaced by one Tucker proposed (the
+last one preferably). That's in mail that hasn't been filed yet.
+
+** TBD: The static rule is completely wrong, according to Adam. It needs to
+be completely replaced.
+
+Adam would like the static expression evaluation rules to
+apply to *all* conditional expressions that have a static condition.
+He points out that cases like that can't happen in short circuit expressions.
+His main point is that if the unevaluated subexpression is static, it
+could make the entire expression illegal. For example:
+
+ (if N = 0 then Some_Function else 10000 / N)
+
+If N is statically zero, this is still not a static expression. With the
+proposed rules, a compiler is required to evaluate the else part
+statically, triggering 4.9(33) and making the expression illegal.
+Argubly, that's OK (the function call here is suspicious). We need
+to decide what to do.
+** end TBD.
+
+
!discussion
@@ -3292,7 +3318,8 @@
> parenthesis
> or the expression as missing, showing the correct point of the error.
-I agree, regarding the above example of "exit". But it would be nice if we could say:
+I agree, regarding the above example of "exit". But it would be nice if we
+could say:
pragma Assert(if A then B);
@@ -3330,8 +3357,8 @@
> We allow the "else" branch to be omitted for boolean-valued
> conditional expressions. This eases the use of conditional expressions
-> in preconditions and postconditions, as it provides a very readable form of the "implies"
-> relationship of Boolean algebra. That is,
+> in preconditions and postconditions, as it provides a very readable form
+> of the "implies" relationship of Boolean algebra. That is,
> A implies B
> could be written as
> (if A then B)
@@ -3670,7 +3697,8 @@
From: Edmond Schonberg
Sent: Tuesday, March 17, 2009 8:50 AM
-I suspect the "if" at the beginning stays (it's N to 1 in favor, with N >> 1). The closer does seem superfluous,
+I suspect the "if" at the beginning stays (it's N to 1 in favor, with N >> 1).
+The closer does seem superfluous,
****************************************************************
@@ -4393,3 +4421,472 @@
a legality rule than syntax - no big deal.
****************************************************************
+
+From: Adam Beneschan
+Sent: Monday, March 23, 2009 12:37 PM
+
+!topic AI05-0147 (Conditional expressions)
+!reference AI05-0147
+!from Adam Beneschan 09-03-23
+!discussion
+
+I think this AI just became available on the ada-auth web site, so I've been
+looking it over. I'd definitely appreciate this being part of the language; I
+think I've run into a good number of cases in the past where having this would
+have been very useful. And thanks for requiring the parentheses. I have a
+vague memory of seeing an example like this in a book, a long time ago, where I
+think the language was some flavor of Algol:
+
+ if if if if A then B else C then D else E then F else G then ...
+
+I have a few comments about the proposed changes to 4.9. Here's the text as it
+currently appears on
+http://www.ada-auth.org/cgi-bin/cvsweb.cgi/ai05s/ai05-0147-1.txt?rev=1.2 :
+
+===============================================================================
+Split 4.9(33), replacing it by the following:
+A static expression is evaluated at compile time except when:
+* it is part of the right operand of a static short-circuit control
+ form whose value is determined by its left operand;
+* it is part of a condition of some part of a conditional_expression,
+ and at least one and at least one condition of a preceeding part of
+ the conditional_expression has the value True; or
+* it is part of the dependent_expression of some part of a
+ conditional_expression, and the associated condition evaluates to
+ False; or
+* it is part of the dependent_expression of some part of a
+ conditional_expression, and at least one condition of a preceeding
+ part of the conditional_expression has the value True.
+===============================================================================
+
+My comments:
+
+(1) "preceding" is misspelled.
+
+(2) The second bullet point repeats the four words "and at least one"
+ twice.
+
+(3) I think the language "and the associated condition evaluates to
+ True" [or False] is a bit confusing, because at first glance, it's
+ mixing run-time and compile-time ideas. Most of the time, the
+ compiler won't know what the condition evaluates to, but the
+ language suggests that the compiler needs to know in order to
+ decide whether a certain expression is to be statically evaluated.
+
+ I'd suggest that to clarify things, the phrase be reworded as "and
+ the associated condition is a static expression whose value is
+ True". I could live with "and the associated condition statically
+ evalates to True", but the first phrasing relies on terms that are
+ already defined. In any case, I think the intent is that if the
+ condition is not a static expression, the bullet point doesn't
+ apply, and thus the condition can't prevent the "static
+ expression" referred to by the first phrase of 4.9(33) from being
+ evaluated.
+
+ Anyway, it may be necessary to clarify the intent in a case like
+ this:
+
+ (if (Constant_1 and then Func_Call(...)) then Expr_1 else Expr_2)
+
+ Suppose Constant_1 is a constant whose value is False, and that
+ Expr_1 is a static expression. Now we know Expr_1 will never be
+ evaluated. However, the condition "Constant_1 and then Func_Call"
+ is not a static expression, even though the compiler can tell that
+ its value is always False. I believe that this clarification is
+ needed, or at least useful to a reader, in order to determine
+ whether the compiler will evaluate Expr_1 at compile time (and
+ possibly make the program illegal by 4.9(34)).
+
+ [At first I thought that this probably also existed in the first
+ bullet point, which has been around since Ada 95. However, the
+ first bullet point only applies to a "static short-circuit control
+ form", which means that the left-hand relation would have to be
+ static anyway. The other bullet points apply to all
+ conditional_expressions, not just static ones, so it's different.]
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March 23, 2009 2:27 PM
+
+> I think this AI just became available on the ada-auth web site, so
+> I've been looking it over. I'd definitely appreciate this being part
+> of the language; I think I've run into a good number of cases in the
+> past where having this would have been very useful. And thanks for
+> requiring the parentheses. I have a vague memory of seeing an example
+> like this in a book, a long time ago, where I think the language was
+> some flavor of Algol:
+>
+> if if if if A then B else C then D else E then F else G then ...
+
+There has been a lot of discussion about this proposal over on the ARG list; it
+some point there will be a new draft reflecting the additional ideas.
+
+> I have a few comments about the proposed changes to 4.9.
+...
+> [At first I thought that this probably also existed in the first
+> bullet point, which has been around since Ada 95. However, the
+> first bullet point only applies to a "static short-circuit control
+> form", which means that the left-hand relation would have to be
+> static anyway. The other bullet points apply to all
+> conditional_expressions, not just static ones, so it's different.]
+
+That's definitely not intended. I obviously failed to notice that "static" is
+repeated in the short circuit case. That should be the case for the conditional
+expressions as well - these bullets only apply to a static conditional
+expression. Please imagine that it is there and tell me if there are any other
+problems with the wording (other than the typos).
+
+****************************************************************
+
+From: Adam Beneschan
+Sent: Monday, March 23, 2009 2:49 PM
+
+But is making the bullet points apply only to "static conditional expression"
+correct? If N is a constant with value 0, it means that you couldn't use the
+expression
+
+ (if N = 0 then Max_Value_For_System else 10_000 / N)
+
+if Max_Value_For_System is, say, a function call, because the existence of the
+function call makes this *not* a static conditional_- expression, and then the
+compiler would have to statically evaluate the "else" expression.
+
+I thought the intent was that in the case
+
+ if A then B else C
+
+if A is a static expression whose value is True, then the compiler wouldn't
+evaluate C even if it is a static expression. That probably ought to be the
+case whether or not B is a static expression---the staticness of B should be
+irrelevant. (And similarly in the mirror case where A is statically False.)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March 23, 2009 3:45 PM
+
+...
+> But is making the bullet points apply only to "static conditional
+> expression" correct?
+
+Yes. :-)
+
+> If N is a constant with
+> value 0, it means that you couldn't use the expression
+>
+> (if N = 0 then Max_Value_For_System else 10_000 / N)
+>
+> if Max_Value_For_System is, say, a function call, because the
+> existence of the function call makes this *not* a static
+> conditional_- expression, and then the compiler would have to
+> statically evaluate the "else" expression.
+
+That is exactly the intent. I didn't think this expression would fly if it
+introduced a new concept - the "partially static expression". Besides, you could
+make the same argument for short circuit expressions, and
+
+ N = 0 or else Max_Value_For_System > 10_000
+
+is never a static expression, even if N = 0.
+
+I think the argument is that the language designers did not want whether or not
+an expression is static to depend on the values. If the rule you are suggesting
+was the case, then
+
+ Max : constant := (if N = 0 then Max_Value_For_System else 10_000 / N)
+
+would be illegal because this is not an static expression if N = 0, and legal
+otherwise.
+
+****************************************************************
+
+From: Adam Beneschan
+Sent: Monday, March 23, 2009 4:08 PM
+
+> That is exactly the intent. I didn't think this expression would fly
+> if it introduced a new concept - the "partially static expression".
+
+I don't see why a new concept would be needed. Please see my earlier post; all
+I was suggesting was changing this (with typos eliminated)
+
+* it is part of a condition of some part of a conditional_expression,
+ and at least one condition of a preceding part of the
+ conditional_expression has the value True; or
+
+to
+
+* it is part of a condition of some part of a conditional_expression,
+ and at least one condition of a preceding part of the
+ conditional_expression is a static expression with the value True;
+ or
+
+and similarly for the next two paragraphs. Why would a new concept be needed?
+My suggestion didn't refer at all to whether the entire conditional_expression
+was static or not. Your response added that. I am certainly not suggesting
+changing the definition of whether a conditional_expression is static.
+
+
+> Besides, you
+> could make the same argument for short circuit expressions, and
+>
+> N = 0 or else Max_Value_For_System > 10_000
+>
+> is never a static expression, even if N = 0.
+
+But then the argument wouldn't apply at all. The question has to do with when a
+static expression is evaluated according to 4.9(33), when it's part of a larger
+conditional expression. Here, "Max_Value_For_System > 10_000" isn't a static
+expression, so 4.9(33) doesn't apply to it at all.
+
+The argument doesn't apply equally to short-circuit expressions and
+conditional_expressions, for this reason: For the "exception" mentioned in
+4.9(33) to apply, so that a static expression isn't evaluated, first of all you
+have to have a static expression to apply this clause to, and second of all it
+has to depend on a condition that is also a static expression. That's two
+expressions that need to be static. In a short-circuit expression, there are
+only two expressions anyway. So it's OK for the first bullet point to say it
+only applies to a *static* short-circuit expression. In a
+conditional_expression, there's (possibly) a third expression. My suggestion
+here is that the remaining three bullet points should still depend *only* on the
+static expression in question *and* on the condition, *not* on whether the third
+expression is static. That's why the argument doesn't apply equally.
+
+
+> I think the argument is that the language designers did not want
+> whether or not an expression is static to depend on the values. If the
+> rule you are suggesting was the case, then
+>
+> Max : constant := (if N = 0 then Max_Value_For_System else 10_000
+> / N)
+>
+> would be illegal because this is not an static expression if N = 0,
+> and legal otherwise.
+
+I don't think that's the issue, though. Yes, the above example should be
+illegal; the conditional expression shouldn't be static and shouldn't be allowed
+where a static expression is required. That wasn't my point. My concern has to
+do with when a static expression that is ***part of*** a larger conditional
+expression is evaluated and could possibly make the program illegal. In this
+example:
+
+ (if N = 0 then Max_Value_For_System else 10_000 / N)
+
+10_000 / N is a static expression (if N is static), and I don't believe the
+compiler should try to evaluate it if N is 0. Whether or not the whole
+conditional_expression is static is, I believe, not important to this issue.
+And I didn't make it part of the issue. As I mentioned, you're the one who
+brought the "static conditional_expression" wording into it, and my feeling is
+that doing so was incorrect.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March 23, 2009 4:39 PM
+
+...
+> and similarly for the next two paragraphs. Why would a new concept be
+> needed?
+
+There is no concept in Ada of statically evaluating *part* of an expression.
+You are asking to add one.
+
+...
+> > Besides, you
+> > could make the same argument for short circuit expressions, and
+> >
+> > N = 0 or else Max_Value_For_System > 10_000
+> >
+> > is never a static expression, even if N = 0.
+>
+> But then the argument wouldn't apply at all. The question has to do
+> with when a static expression is evaluated according to 4.9(33), when
+> it's part of a larger conditional expression. Here,
+> "Max_Value_For_System > 10_000" isn't a static expression, so 4.9(33)
+> doesn't apply to it at all.
+
+Which is my point: if the conditional expression is not static, 4.9(33) does not
+apply to it at all.
+
+> The argument doesn't apply equally to short-circuit expressions and
+> conditional_expressions, for this reason: For the "exception"
+> mentioned in 4.9(33) to apply, so that a static expression isn't
+> evaluated, first of all you have to have a static expression to apply
+> this clause to, and second of all it has to depend on a condition that
+> is also a static expression.
+> That's two expressions that need to be static. In a short-circuit
+> expression, there are only two expressions anyway. So it's OK for the
+> first bullet point to say it only applies to a *static* short-circuit
+> expression. In a conditional_expression, there's (possibly) a third
+> expression. My suggestion here is that the remaining three bullet
+> points should still depend *only* on the static expression in question
+> *and* on the condition, *not* on whether the third expression is
+> static. That's why the argument doesn't apply equally.
+
+Actually, there is an unlimited number of other expressions in a conditional
+expression (all of the "elsif" branches). You want to require some of them to be
+evaluated statically, and others not, depending on the values of still other
+others, *and* you want that to happen in a non-static context (so that it isn't
+obvious whether the rule is even applied to a particular expression). That's
+just too complex in my view.
+
+...
+> In this example:
+>
+> (if N = 0 then Max_Value_For_System else 10_000 / N)
+>
+> 10_000 / N is a static expression (if N is static), and I don't
+> believe the compiler should try to evaluate it if N is 0. Whether or
+> not the whole conditional_expression is static is, I believe, not
+> important to this issue. And I didn't make it part of the issue. As
+> I mentioned, you're the one who brought the "static
+> conditional_expression" wording into it, and my feeling is that doing
+> so was incorrect.
+
+If this is not a static expression, the compiler shouldn't be evaluating any of
+it. So what's the problem?
+
+****************************************************************
+
+From: Adam Beneschan
+Sent: Monday, March 23, 2009 5:08 PM
+
+> There is no concept in Ada of statically evaluating *part* of an expression.
+
+GNAT rejects this:
+
+ procedure Test783 (Param : Integer) is
+ N : constant := 0;
+ X : Integer := Param + (10 / N);
+ begin
+ null;
+ end Test783;
+
+Are you saying GNAT is wrong?
+
+I think GNAT is right, the way I read the RM. 10 / N is a static expression.
+The syntax of "expression" in 4.4 clearly indicates that expressions can be part
+of larger expressions. 4.9(2-13) defines when an expression is a static
+expression, and the definition doesn't care whether the expression is part of a
+larger expression or not. 4.9(33) says that static expressions are evaluated at
+compile time, and that rule doesn't care whether the expression is part of a
+larger expression or not, except in one particular case involving short
+circuits. In particular, the rule doesn't care whether the static expression is
+part of a larger nonstatic expression.
+
+Anyway, that's how I've always interpreted the RM; it would come as a complete
+surprise to me to find that 4.9(33) doesn't apply to static expressions that are
+part of larger expressions. I don't see any wording in the RM to support that
+interpretation.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, March 23, 2009 8:26 PM
+
+...
+> Are you saying GNAT is wrong?
+
+Yes, but...
+
+> I think GNAT is right, the way I read the RM. 10 / N is a static
+> expression. The syntax of "expression" in 4.4 clearly indicates that
+> expressions can be part of larger expressions.
+> 4.9(2-13) defines when an expression is a static expression, and the
+> definition doesn't care whether the expression is part of a larger
+> expression or not. 4.9(33) says that static expressions are evaluated
+> at compile time, and that rule doesn't care whether the expression is
+> part of a larger expression or not, except in one particular case
+> involving short circuits. In particular, the rule doesn't care
+> whether the static expression is part of a larger nonstatic
+> expression.
+>
+> Anyway, that's how I've always interpreted the RM; it would come as a
+> complete surprise to me to find that 4.9(33) doesn't apply to static
+> expressions that are part of larger expressions. I don't see any
+> wording in the RM to support that interpretation.
+
+Unfortunately, I think you are right (although I don't think that the ACATS
+requires any of this). For the record, Janus/Ada does not reject this example
+(although it does give a warning). It appears to me that this was the Ada 83
+rule (exact evaluation was only required for universal expressions), and I'm
+surprised that I was not aware of the change. (Janus/Ada probably goes out of
+its way to *not* produce an error in this case, since it evaluates everything
+that it can with the exact evaluation machinery.)
+
+But I'm very worried about the effect in generics. Janus/Ada's generic code
+sharing depends completely on the fact that there cannot be any "interesting"
+static expressions in generics. If that's not true in some (important) case,
+then code sharing is impossible.
+
+Anyway, obviously, I have no clue how static expressions work, so you should
+disregard everything I've written on the subject. In particular, you should
+completely discard the bullets I wrote, because I made no consideration of the
+possibility of non-static expressions coming into 4.9(33). I doubt that anything
+is correct about them in that case; they'll need to be completely reanalyzed,
+and there are many more cases to consider (such as rounding issues, discriminant
+checks, etc.).
+
+[Note from Randy, November 3, 2009: One important point to remember that I
+forgot in this discussion is that an expression being static has nothing
+to do with whether it is evaluated exactly. 4.9(33-37) *do not* apply to
+static expressions that are not evaluated. So most of Adam's argument is
+bogus -- 10_000/N can be a static expression, and N can be zero, but it
+still is legal if it is not evaluated. The important question is whether
+we want to allow random non-static function calls in static expressions
+even if they are not evaluated. I think the answer is no.]
+
+****************************************************************
+
+From: Georg Bauhaus
+Sent: Tuesday, March 23, 2009 6:26 AM
+
+>> I think this AI just became available on the ada-auth web site, so
+>> I've been looking it over. I'd definitely appreciate this being part
+>> of the language; I think I've run into a good number of cases in the
+>> past where having this would have been very useful. And thanks for
+>> requiring the parentheses. I have a vague memory of seeing an
+>> example like this in a book, a long time ago, where I think the
+>> language was some flavor of Algol:
+>>
+>> if if if if A then B else C then D else E then F else G then ...
+
+Some of my increasingly stressed hair is pointing upwards.
+
+When I saw conditional expression as currently outlined, I thought they will
+definitely need good bridles. Aren't you otherwise inviting programmers to
+violate at least three Ada commandments:
+
+1/ Name things!
+2/ Read linearly!
+3/ Don't leave holes, cover everything!
+
+As follows.
+
+First, regarding 1, 2: do not let all too clever nesting sneak in via
+conditional expressions (to illustrate the danger, add obvious fantasies to the
+if if if if above). Require a renaming:
+
+ Safe_Bound: Natural renames
+ (if N = 0 then 10_000 else 10_000 / N);
+
+ subtype Calculation_Range is Natural range 0 .. Safe_Bound + 1;
+
+In preconditions, where there is no declarative region at hand, we can write
+normal function calls, no change here. Consequently, a lazy author's ad hoc
+nested (if ...) is precluded in preconditions without loss.
+
+And (regarding 3) Please, Please, Please, have the conditional expressions cover
+all cases!!! Have us fully state what we mean. Do not permit telling half
+truths for the sake of being negligent: the ELSE is a must here.
+
+I noticed the following comment on the AI
+
+ " b) people love complex boolean expressions and insist on filling
+ their code with them, the more complex the better :-( "
+
+Don't invite us to do so. Please. (Because computer programming is not
+recreational mathematics; it is enough like forensic logic as is ...)
+
+****************************************************************
+
Questions? Ask the ACAA Technical Agent