See Table 12.1: Precedence of operators at https://www.freepascal.org/docs-html/ref/refch12.html#x139-16100012 (https://www.freepascal.org/docs-html/ref/refch12.html#x139-16100012)Ah, that's where the table I was looking for is. :-[
Ah, that's where the table I was looking for is. :-[Yes, I hope you agree precedence for Boolean operators is unclear.
[…] evaluation in Pascal is left to right […]FPC may re-arrange expressions though as it think it’s best. One heuristic is “evaluate more ‘complex’ sub-expressions first, and then turn to ‘simple’ sub-expressions.”
Actually all Boolean operators have equal weight and evaluation in Pascal is left to right, ...
[…]= belongs to the category of “relational operators”, which comes third in precedence. I still don’t understand how and where any ambiguity may arise.
What is this “weight” you’re talking about?Quite simply, mathematical operators have a defined precedence. See here: https://en.wikipedia.org/wiki/Order_of_operations
Actually all Boolean operators have equal weight and evaluation in Pascal is left to right, so not binds only to the first condition and and binds the result to the second condition.Well, unary operators have to have higher precedence.
In an expression
a and not b
you have to evaluate "not b" before evaluation of "and".
Yes, of course. But nevertheless, it means that "not" has precedence over other boolean operators, which contradicts earlier statement that they all are equal.
boolean_expression and boolean_expression
so it examines things closely and finds "a" on the left and "not" on the right. That "not" cannot be by itself, so it looks a little more and decides that the right expression is "not b". Done.Yes, of course. But nevertheless, it means that "not" has precedence over other boolean operators, which contradicts earlier statement that they all are equal.No. You really do not understand this. Not has equal weight. a and not b will negate b. Basics. Real basics.
[…] See here: https://en.wikipedia.org/wiki/Order_of_operations (https://en.wikipedia.org/wiki/Order_of_operations)Yeah, I knew that, I simply never called it “weight” (and neither did the Wikipedia authors). For me weight is a concept from physics.
These operators differ in weight.
Boolean operators do not have a defined precedence, they are all equal and their evaluation by the compiler is left to right.Huh??? That surprises me, though. Boolean operators are obviously mentioned in the precedence table in chapter “expressions” of the reference manual (https://www.freepascal.org/docs-html/ref/refch12.html), are they not?
Huh??? That surprises me, though. Boolean operators are obviously mentioned in the precedence table in chapter “expressions” of the reference manual (https://www.freepascal.org/docs-html/ref/refch12.html), are they not?
[…] IIRC, those mentioned in that table are not the boolean operators but the bitwise (logical) ones. I may be wrong, though.Yeah, I had that idea, too, but that isn’t plausible, § Boolean operators (https://www.freepascal.org/docs-html/ref/refsu47.html): “Boolean operators can be considered as logical operations on a type with 1 bit size.” Ergo, you can just ignore the fact Pascal defines a dedicated Boolean data type and treat everything as integers, just as C does. The operator precedence table retains its validity.
a and not b will negate b.This is perfectly unclear statement.
The net result is to make it look as if it had precedence, but it isn't really so.If it always looks like it has precedence, maybe it is more simple to say that it has precedence?
The net result is to make it look as if it had precedence, but it isn't really so.If it always looks like it has precedence, maybe it is more simple to say that it has precedence?
not a and b
the fact that it means(not a) and b
is just an artifact of left-to-right parsing; parsed right-to-left it would mean:not (a and b)
.The short hand evaluation of Boolean expression can be controlled using the $B directive. See here (https://www.freepascal.org/docs-html/current/prog/progsu4.html#x11-100001.2.4).a and not b will negate b.This is perfectly unclear statement.
Obviously, here "a" will be evaluated, if it is false, no further processing continues and "false" is returned, because FPC, as far as I remember, uses lazy evaluation.
If "a" is true, it evaluates "not b"; if "not b" is false, it stops with "false" as result, otherwise "and" is evaluated and "true" returned.
Obviously, this is much more than just negation of b.
So, what did you want to say apart from being arrogant, as usually, is not clear.
The order of parsing will not change, because that's part of the Pascal standard (no matter if early Wirth's Pascal, ISO Pascal or Delphi language).The net result is to make it look as if it had precedence, but it isn't really so.If it always looks like it has precedence, maybe it is more simple to say that it has precedence?
When talking informally, yes, maybe; but in a technical forum one should strive to be as precise as one can. At least that's what I think.
For example, iin:Code: [Select]not a and b
the fact that it meansCode: [Select](not a) and b
is just an artifact of left-to-right parsing; parsed right-to-left it would mean:Code: [Select]not (a and b)
.
I don't think it will change tomorow (or ever, if for nothing else than backwards compatibility) but it might, and one has to be aware of it.
Or I may be completely wrong. It can happen too :)
writeln (false and foo_a() or foo_b());
Output:It was a good idea if the compiler could optimize such code by removing the call to the t1 function, which does not affect the result. The side effect of calling a function here is still not guaranteed by the documentation.
t1 was called
t2 was called
TRUE
Output:It was a good idea if the compiler could optimize such code by removing the call to the t1 function, which does not affect the result. The side effect of calling a function here is still not guaranteed by the documentation.
t1 was called
t2 was called
TRUE
but to guarantee the evaluation order?And where does it say that the operands of a binary operation should be calculated in the order of writing?
but to guarantee the evaluation order?And where does it say that the operands of a binary operation should be calculated in the order of writing?
I would swore I have read it somewhere (in legit docs) but I'm unable to find it now, so I may be wrong :-[In fact, it seems logical, otherwise it was difficult to predict the behavior of such an expression:
somewhere it is documented : left to right evaluation.but to guarantee the evaluation order?And where does it say that the operands of a binary operation should be calculated in the order of writing?
Remark: The order in which expressions of the same precedence are evaluated is not guaranteed to be left-to-right. In general, no assumptions on which expression is evaluated first should be made in such a case. The compiler will decide which expression to evaluate first based on optimization rules.
Otherwise we would have trouble with
If assigned (someproc) then
Someproc(param1,param2);
You are aware that constant expressions are evaluated at compile-time? The behavior may differ between compile-time and run-time.
[…] writeln (true or true and false); writeln (false and true or true); […]
[…] ANDing two numbers meant multiplying them... […]Well, that’s still true: In electrical engineering the notation AB (with invisible “times”) means A ∧ B.
If some of the high priests of FPC decided to change the left to right order of conditionals, FPC would be dead. […]There’s no room for discussion: The ISO 7185 again defines (http://www.pascal-central.com/iso7185.html#6.7.1%20General): “[…] operators of the same precedence shall be left associative.” Wirth originally stated (http://www.pascal-central.com/docs/pascal1973.pdf) (PDF page 24): “Sequences of operators of the same precedence are executed left to right.”
That's the same order I wrote....Didn't you say that boolean expressions are evaluated from left to right and "and" and "or" have the same priority? Reply #3: "Actually all Boolean operators have equal weight and evaluation in Pascal is left to right"
t(0) and t(1) and t(2) or t(3) and t(4) or t(5).
( t(0) and t(1) and t(2) ) or
( t(3) and t(4) ) or
t(5)
This can be understood if AND has a higher priority than OR. The expression can be rewritten like thisI've been reading this thread and wondering when someone was going to show that the "left to right" evaluation only applies to operators that have the same precedence and precedence varies among the Boolean operators.Code: [Select]( t(0) and t(1) and t(2) ) or
( t(3) and t(4) ) or
t(5)
Since the first part of the OR expression, (t(0) and t(1) and t(2)), already yields TRUE which cannot be changed by the next OR expression only t(0), t(1) and t(2) need to be evaluated.
The rules of composition specify operator precedences according to four classes of operators. The operator not has the highest precedence, followed by the so-called multiplying operators, then the so-called adding operators, and finally, with the lowest precedence, the relational operators. Sequences of operators of the same precedence are executed from left to right. The rules of precedence are reflected by the following syntax:
<BNF syntax and examples removed>
<The operators are listed in order of precedence (highest precedence first)>
8.1.1. The operator not
The operator not denotes negation of its Boolean operand.
8.1.2. Multiplying operators
<multiplying operator> ::= * | / | div | mod | and
8,1.3. Adding operators
<adding operator> ::= + | - | or
8.1.4. Relational operators
<relational operator> ::= = | <> | < | <= | >= | > | in
Pure Boolean operators are equal weight.Pure Boolean operators ? ... unlike the impure Boolean operators, those go to Church ? ... them Boolean sinners.
(Boole would probably have turned in his grave)He is probably spinning by now.
In fact, it seems logical, otherwise it was difficult to predict the behavior of such an expression:It is really unclear in current docs, so I recently reported exactly this, then Michael updated the docs for 3.2 -- https://bugs.freepascal.org/view.php?id=35661 (https://bugs.freepascal.org/view.php?id=35661)But for some reason in the documentation this was not explicitly mentioned.
if Assigned(P) and (P^...)...
It is really unclear in current docs, so I recently reported exactly this, then Michael updated the docs for 3.2 -- https://bugs.freepascal.org/view.php?id=35661 (https://bugs.freepascal.org/view.php?id=35661)Thanks. In the repository "fpcdocs" in the file "ref.tex" there is an addition:
He is probably spinning by now.Permanently.... :)
I've been reading this thread and wondering when someone was going to show that the "left to right" evaluation only applies to operators that have the same precedence and precedence varies among the Boolean operators.
...
I always use parenthesis in these cases. It forces a precedence and is clear to read. (Even if I don't "really" need them)
Which means one (more) thing for me to stop and study carefully :)I think the simplest way of understanding the Boolean precedence rules is how Jensen & Wirth presented them in their Pascal report.
@440bx: That post just won a honor place in my "Important notes" file. :DMy pleasure. I hope other people find it helpful too. The equivalences comes directly from Jensen and Wirth's presentation in their Pascal report. IOW, we both owe them that clear, understandable explanation.
Thanks.
That's not correct Howard. Hence the bug report against documentation. Pure Boolean operators are equal weight.No, Howard is correct. See compiler/tokens.pas:
(Boole would probably have turned in his grave)
4. Term beyond 'and' is always evaluated to find value of full expression, i.e. '... and ...'
Yes, please see my modified list of rules.4. Term beyond 'and' is always evaluated to find value of full expression, i.e. '... and ...'
I expect the term beyond 'and' only to be evaluated when the first expression is true.
The really significant difference between an arithmetic expression and a Boolean expression is that, in the case of an arithmetic expression it is normally necessary to fully evaluate it to determine the result.
Well, generally even for arithmetic it is not always necessary. Consider an expression: a*(b+c) where a = 0.That's correct. That's why I stated "it is normally necessary...". In the expression you used, as you pointed out, if the compiler could reliably determine that a = 0 then it wouldn't have to evaluate the expression to know the result will be zero.