Discussion

Why all the arguments of an IF statement are evaluated?

2

Jeanmilost 2023-02-17 22:53 (Edited)

Hello all,

I recently noticed an unexpected behavior in the way the code is executed in LowResNX. Consider the following code:
IF A = 0 AND B = 0 THEN

END IF

As a C/C++ developer, I expect that the statement B = 0 would never be evaluated if A <> 0, because it would no longer be possible that the result may success in this case. But it seems that LowResNX continue to evaluate all the statements even if the first one turns the result impossible.

This is annoying for at least 2 reasons:
1. This force the code to be over complicated in some situation, e.g the below code:
IF INDEX < UBOUND(ARRAY) AND ARRAY(INDEX) = X THEN …
need to be written in the following manner to work as expected:
IF INDEX < UBOUND(ARRAY) THEN
IF ARRAY(INDEX) = X THEN

2. It seems to me (but perhaps I’m wrong) that this uses some processor cycles for nothing

So my questions are:
1. Is it a bug, or is it the correct way the Basic language should behave?
2. In case it’s a bug, is there a chance to be fixed one day?


McPepic 2023-02-18 00:15

I noticed this as well. It just seems to be a quirk with Timo's implementation of BASIC in LowRes. In case you want to fit it on one line, you can do:
IF A = 0 THEN (IF B = 0 THEN ...)
This way, it will only evaluate B if the first part returns true.


was8bit 2023-02-18 04:31 (Edited)

I believe AND works as a math function, not as a logical function... so it must calculate the entire thing to yield a numeric result, which THE NUMERIC RESULT will determine if the IF statement will then perform the THEN statement

It is also ok to say

IF A+B THEN.....

as A+B will yield a numeric result that the IF statement will use...

... for example

IF 1+2 THEN PRINT "HI"

Will print "HI"

Conversely..

IF 1-1 THEN PRINT "HI" ELSE PRINT "NO"

Will print "NO"


was8bit 2023-02-18 04:38

For fun, try this out ;)

FOR A=0 TO PI*2 STEP 0.1
IF (COS(A)-SIN(A))\1.5 THEN PRINT "Y"; ELSE PRINT ".";
NEXT A


was8bit 2023-02-18 04:43

Or this...

FOR ISTEP=1 TO 0.1 STEP -0.1
FOR A=0 TO PI*4 STEP ISTEP
IF (COS(A)-SIN(A))\1.5 THEN S=40 ELSE S=60
PLAY 0,S,1
WAIT VBL
NEXT A
NEXT ISTEP


Timo 2023-02-18 08:34

In BASIC then AND and OR operations are binary and just work „accidentally“ also as logical operators.
So as was8bit said, they just calculate a value and the final value is checked by IF.


Timo 2023-02-18 08:42

In any case I also just forgot to think about implementing the optimization, later noticed the “bug”, thought about fixing it, and then noticed, that it’s not a bug.

Actually, AND could be optimized, if one value is 0 then the result will be 0, but for OR it’s not possible: If the first value is different than 0, then it still needs to do the binary operation with the second value.


Jeanmilost 2023-02-20 21:09 (Edited)

@all thanks for the answers, it’s very interesting. And ok, I’ll keep in mind how the statements work on my future developments.

@timo I disagree, for an OR operator, and contrary to a AND, if the first statement is true, then the second one don’t need to be evaluated, because the result will always be true in this case. As far as I know the only case where the both statements need to be evaluated is for a XOR instruction.

But let me know if I’m wrong, it would be interesting for me to know the reason why.


nathanielbabiak 2023-02-21 03:21 (Edited)

What you're hoping for is short-circuit evaluation, a construct in modern programming languages.

Most of the flavors of basic use the opposite, called lazy evaluation; it's actually the expected behavior.

Most of the early flavors of basic didn't allow functions, so the computation time of evaluating expressions was simply overlooked.


Timo 2023-02-21 09:19

%11110000 OR %00001111
= %11111111

As OR is a binary operator, it needs to evaluate both sides. If it was a logical operator, the left value would make it true already, but to get a correct binary result, it needs to use both values.


Timo 2023-02-21 09:41

@nathanielbabiak My understanding of the wiki article is, that "lazy evaluation" is usually also short-circuit. LowRes NX is not lazy, it always evaluates all values ;)


nathanielbabiak 2023-02-21 12:33

Yep, you're right, my response was all mixed up!


Jeanmilost 2023-02-22 20:09

@timo @nathanielbabiak ok got it 🙂Thanks for the explanations


Log in to reply.