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

Differences between 1.4 and version 1.5
Log of other versions for file 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