Talk:Short-circuit evaluation: Difference between revisions

From Rosetta Code
Content added Content deleted
Line 58: Line 58:
* In ''Z = F(X) .AND. Y'', the ''F(X)'' part may, or may not, be evaluated. This could of course be a problem if ''F'' has side effects.
* In ''Z = F(X) .AND. Y'', the ''F(X)'' part may, or may not, be evaluated. This could of course be a problem if ''F'' has side effects.
* However, in ''Z = F(X) . AND. G(Y)'', if ''F(X)'' has side effects that change the value of ''G(Y)'', this is not standard conformant: ''The evaluation of a function reference shall neither affect nor be affected by the evaluation of any other entity within the statement.'' (7.1.8)
* However, in ''Z = F(X) . AND. G(Y)'', if ''F(X)'' has side effects that change the value of ''G(Y)'', this is not standard conformant: ''The evaluation of a function reference shall neither affect nor be affected by the evaluation of any other entity within the statement.'' (7.1.8)

Therefore, you cant rely on short-circuiting in Fortran, and you have to use a nested IF, as Paddy3118 remarks. Even if one particular Fortran compiler guarantees short-circuit evaluation (maybe with a command-line option), using this feature would not affect standard conformance of the program, but it could certainly affect its successful execution.


[[User:Arbautjc|Arbautjc]] ([[User talk:Arbautjc|talk]]) 10:27, 30 April 2015 (UTC)
[[User:Arbautjc|Arbautjc]] ([[User talk:Arbautjc|talk]]) 10:27, 30 April 2015 (UTC)

Revision as of 10:31, 30 April 2015

Why a draft task?

A comment in here (look for shortcutting), thought that the task would most likely not be written in a neutral manner. I've tried to write a task that allows each language, whether it has short-circuit evaluation or not, to solve the problem idiomatically.
I saw the comments on the Icon solution, for example, which makes me think that the task could soon lose the draft status? --Paddy3118 23:59, 24 July 2010 (UTC)

I removed the draft status as the examples seem to cope (another example is Pascal where some compilers have it and some do not).

Error in task?

The problem states:

  x = a(i) and b(j)
  y = a(j) or  b(j)

But the only example is written as:

  x = a(i) and b(j)
  y = a(i) or  b(j)

Either the definition of the first example is wrong. I'm guessing the task description but ... --Dgamey 17:50, 24 July 2010 (UTC)

You are right of course. Hopefully fixed now, thanks. --Paddy3118 23:43, 24 July 2010 (UTC)

Control structure?

I would be inclined to add the control structure tag to this task. Lisp was one of my early languages to learn, and I always though of short-circuit and and or as control structures. (Of course, as I later learned, many concepts that seem natural and intuitive in Lisp are viewed as insanity by the mainstream imperative programming world....) Anyone else have feelings about adding or not adding the control structure tag? —Sonia 17:18, 20 April 2011 (UTC)


It was used as such for a long time in Python too. value = condition and x or y was used until later syntax additions allowed that to be expressed as value = x if condition else y. So I can see your point. --Paddy3118 17:47, 20 April 2011 (UTC)
In my opinion, short-circuit evaluation is a form of flow of control in any language with side effects. (And, in languages without side effects, flow of control is not a meaningful concept -- there, it's just a question of which results get used, but that should not matter here.) --Rdm 17:44, 20 April 2011 (UTC)
+1 —Ruud 19:17, 20 April 2011 (UTC)

Compiler optimisations?

A variant of this issue arises when the second part of an expression might cause a disaster such as division by zero or indexing out of bounds, as in

while i > 0 and A(i) etc. do i:=i - 1;

where an attempt at A(0) would be improper. The first test protects the second against evaluation only with short-circuiting. A compiler might generate code that always evaluates both parts, or, consistently short-circuits, or, short-circuits only if the first part is a certain sort of expression, such as a boolean variable but not if a function...


Text moved as unclear if it describes fully compliant compiler - If language states short-circuit then compiler should be compliant. --Paddy3118 (talk) 16:07, 28 April 2015 (UTC)
Perhaps apropos is this quote from Charles Moore's 1970 book "PROGRAMMING A PROBLEM-ORIENTED-LANGUAGE" Moreover this attitude is reinforced by the massive trend to high-level languages and a placid acceptance of their inefficiencies: What's the use of designing a really good algorithm if the compiler's going to botch it up anyway? --Rdm (talk) 16:23, 28 April 2015 (UTC)
I do remember posts about non-compliant Pascal and C compilers in the 90's but not so much now and if a language states short-circuit evaluation then a compiler that does not preserve that has a major flaw in my book - short-circuit eval. is a feature big enough not to be missed out in a language compilerd test suit methinks. --Paddy3118 (talk) 16:32, 28 April 2015 (UTC)
Nowadays an issue is command line options and how they interact with subtleties of the language spec. Another issue, though, is where people have mis-read the language spec and [for example] enforce a constraint in the generated code which was meant in the specification to apply to be a constraint on the code supplied to the compiler. --Rdm (talk) 16:48, 28 April 2015 (UTC)
Well, the Turtbo Pascal compiler offered a directive {$B+} to turn on full evaluation instead of the default of short-circuit, and appears to have diligently done so. But here is an extract from the Compaq Fortran 95 compiler...

You should not write logical expressions whose results might depend on the evaluation order of subexpressions. The compiler is free to evaluate subexpressions in any order. In the following example, either (A(I)+1.0) or B(I)*2.0 could be evaluated first:

 (A(I)+1.0) .GT. B(I)*2.0

Some subexpressions might not be evaluated if the compiler can determine the result by testing other subexpressions in the logical expression. Consider the following expression:

 A .AND. (F(X,Y) .GT. 2.0) .AND. B

If the compiler evaluates A first, and A is false, the compiler might determine that the expression is false and might not call the subprogram F(X,Y).

Evidently, this compiler does what it likes in various situations, and there is no sign of any talk about short-circuit options. I recall also discussions of Algol in which an expression (A something)*(B something) might supposedly have the two parts of equal precedence evaluated "in any order". This has always irked me, as I say the order of evaluation is definite: by precedence and, left-to-right, having had experience with the importance of the order of evaluation as in something like e**3/(h*m**2) or somesuch causing exponent overflow: charge&mass of electron, Planck's constant...
Thus, a language (or a compiler manual) may state nothing about short-circuitry, offer no option for it, and do one thing or the other in various circumstances as might be explained in a different context. So I don't think that talking about "compliant" helps, since it appears that Fortran's specifications make no statement and thus a compiler has no promise to deliver on. There is no "meta rule" that holds that all languages must declare their position on this point. In short, I think some such remark about this problem should appear in the heading - the justification for this exercise in needing clarity is not just whether or not an effortsome second function's evaluation could be avoided. Dinosaur (talk) 10:50, 29 April 2015 (UTC)
If short-circuiting isn't covered by the language then the last sentence of the task description should hold: "If the language does not have short-circuit evaluation, this might be achieved with nested if statements." If short-circuiting is covered by the language then a compiler is either wrong or any optimisations must preserve short-circuit operations.
--Paddy3118 (talk) 15:24, 29 April 2015 (UTC)

Just a few notes about Fortran. The references refer to the Fortran 2003 standard.

Short-circuit evaluation is allowed by the standard, but not mandatory: It is not necessary for a processor to evaluate all of the operands of an expression, or to evaluate entirely each operand, if the value of the expression can be determined otherwise. (7.1.8.1) It may be painful if evaluation causes side effects, or when testing for an array index before testing the array value.

  • For example, IF(I < N .AND. A(I) < X) ... may crash the program. In languages with guaranteed short-circuiting, this is a usual construct though.
  • In Z = F(X) .AND. Y, the F(X) part may, or may not, be evaluated. This could of course be a problem if F has side effects.
  • However, in Z = F(X) . AND. G(Y), if F(X) has side effects that change the value of G(Y), this is not standard conformant: The evaluation of a function reference shall neither affect nor be affected by the evaluation of any other entity within the statement. (7.1.8)

Therefore, you cant rely on short-circuiting in Fortran, and you have to use a nested IF, as Paddy3118 remarks. Even if one particular Fortran compiler guarantees short-circuit evaluation (maybe with a command-line option), using this feature would not affect standard conformance of the program, but it could certainly affect its successful execution.

Arbautjc (talk) 10:27, 30 April 2015 (UTC)