The evaluation test, are you up to it?

Which letters are printed?

  • A & B

    Votes: 8 88.9%
  • A & C

    Votes: 0 0.0%
  • B

    Votes: 0 0.0%
  • C

    Votes: 1 11.1%

  • Total voters
    9

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
Me and 2 clan members were discussing in topic topic how conditions were evaluated. I decided to post it here as well, cause this could be quite useful in resolving bugs.
This being said let me point out that we knew this already but rather what has priority.
In mathematics there are specific rules in what order it is calculated, let me give an example.

  1. ^
  2. Square Root
  3. *
  4. /
  5. +
  6. -

  • 1 + 2 * 3 - 4 / 5
  • 1 + 6 - 4 / 5
  • 1 + 6 - 0.8
  • 7 - 0.8

If done correctly, this should be your calculation (1+((2*3)-(4/5))) and the answer should be 6.2.
Now a mathematics calculation isn't too much off from evaluating a condition, just like here you can control the flow of execution by using parenthesis's.
Take a look at this php script for example:
PHP:
$bool = true;

function relapse()
{
	global $bool;

	return $bool = ! $bool;
}

if( $bool || $bool && ! relapse() )
{
	print 'A';
}
if( $bool )
{	
	print 'B';
} 
else 
{
	print 'C';
}

However, what is prioritized in this evaluation?
My guts tell me the "&&" evaluation is skipped because the variable before the or statement returned true already, however there are people who think, or thought otherwise and think the && is evaluated first in wich case the script execution can change completely.

Now I'm not saying that he / she is wrong, because there are many languages out there who may prioritize but usually this is an obsolete thought. You should use parenthesis's by default to avoid any issues with this.
For example, Warcraft III reads this script ( converted to Jass ) from left to right.

However, my question to you is what do you think is the output of this script?
I personally think that this output can differ in different programming languages [Criticism _needed].

Don't test it, just compile this shizzle in your head and just vote what you think the output is!
It is actually quite mind-boggling
 

UndeadDragon

Super Moderator
Reaction score
447
I think that it would print A and B.

BTW, you should use elseif, rather than another if.
 

monoVertex

I'm back!
Reaction score
460
It prints A and B. It's the logical output and I am sure that compiled on an actual PHP platform it will print A and B.

In programming there are also priorities, like in mathematics. And && and || are equal in all the programming languages I have encountered so far. And when two operators are equal, they are read from left to right. I think this happens in every programming language, it is the way that makes most sense. Thus, your condition could be translated into this:

PHP:
if( ( $bool || $bool ) && ! relapse() )

However,

My guts tell me the "&&" evaluation is skipped because the variable before the or statement returned true already

Whut? :nuts: Why it should be skipped? What if the relapse function returned false? If the && would be skipped the function would result in true, but if it would not be skipped (and it's not skipped, regardless of relapse()'s output) then that would return false.

BTW, you should use elseif, rather than another if.

Nah, he actually wants 2 ifs. The second if is just for the sake of testing, the first if is what really matters.
 

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
I think that it would print A and B.

BTW, you should use elseif, rather than another if.

No, I shouldn't! There is a reason why I did this, explained later on.

It prints A and B. It's the logical output and I am sure that compiled on an actual PHP platform it will print A and B.

In programming there are also priorities, like in mathematics. And && and || are equal in all the programming languages I have encountered so far. And when two operators are equal, they are read from left to right. I think this happens in every programming language, it is the way that makes most sense. Thus, your condition could be translated into this:

PHP:
if( ( $bool || $bool ) && ! relapse() )

However,



Whut? :nuts: Why it should be skipped? What if the relapse function returned false? If the && would be skipped the function would result in true, but if it would not be skipped (and it's not skipped, regardless of relapse()'s output) then that would return false.

Why it should be skipped is actually quite simple. $bool = true, it is either $bool being true... and since it is.. the statements behind the || would not needed to be executed.

However, if a language evaluates the entire condition relapse would be called, and $bool would be set to false thus changing the entire script output.
Just as you said, language may prioritize operators such as && and ||. But I have always avoided such confusing by using parenthesis's, but it makes me wounder if languages really do evaluate differently.

A would always be printed, no matter how it is evaluated ( but $bool should stay true ). B is printed when relapse isn't called and C is printed when it is called.

A, B, should be the most logical just as you said but it doesn't have to be that it always is this output in every language. The reason why I got into this topic with a few people and deeply discussed about it.
 

UndeadDragon

Super Moderator
Reaction score
447
Nah, he actually wants 2 ifs. The second if is just for the sake of testing, the first if is what really matters.

Ah. I can see why :p

I think most languages would be able to do this logically and display A and B.
 

monoVertex

I'm back!
Reaction score
460
Okay, I get the point now, I overlooked the fact that $bool changes its value in the relapse() function (human error, lol). This snippet actually shows A and C. I do not think that the relapse() call is skipped.

Why it should be skipped is actually quite simple. $bool = true, it is either $bool being true... and since it is.. the statements behind the || would not needed to be executed.

This does not seems logical to me. Exactly for the reason that && and || are equal in priorities. Even if the result of the || is true, the code cannot be sure (to say so) that this result is not changed by a && later in the condition. Thus, it is not safe to skip the remaining actions.

I will test this code in several languages tomorrow and I will share my results. I think A and C will be :p.


As a conclusion, I do not think that the && is evaluated first, but I also disagree with the fact that the evaluation skips it, when evaluating || first.
 

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
Okay, I get the point now, I overlooked the fact that $bool changes its value in the relapse() function (human error, lol).
I know right, the script is quite confusing :eek:

This snippet actually shows A and C. I do not think that the relapse() call is skipped.
Converting this script to just Jass, it seems that that language evaluates otherwise.

This does not seems logical to me. Exactly for the reason that && and || are equal in priorities. Even if the result of the || is true, the code cannot be sure (to say so) that this result is not changed by a && later in the condition. Thus, it is not safe to skip the remaining actions.
This is exactly why I brought this up. I never really thought about this until a few weeks ago, me being cut off from the world ( no Internet at home ), it made me think, a lot..
I personally think A and B would be printed, because the evaluation returned true already.

I will test this code in several languages tomorrow and I will share my results. I think A and C will be :p.
Revote! :D
 

UnknowVector

I come from the net ... My format, Vector.
Reaction score
144
It will print A and B.

contact at bsorin dot romania said:
07-Mar-2009 04:28
This has got the better part of my last 2 hours, so I'm putting it here, maybe it will save someone some time.

I had a

if (function1() && function2())

statement. Before returning true or false, function1() and function2() had to output some text. The trick is that, if function1() returns false, function2() is not called at all. It seems I should have known that, but it slipped my mind.

PHP will detect that the first disjunct is true and ignore the conjunction. It will never execute relapse, and will never invert the value of $bool.

Off-topic, if you guys want to put a link in the quote by section of a quote tag, you need to strip the protocol identifier, otherwise the forum tries to mark it with url tags and it displays the link all wrong. I just learned this lesson.
 

Samuraid

Advisor
Reaction score
81
PHP's expressions short circuit, so A and B would be printed. At least I think they would. My mind is not necessarily as accurate at evaluating PHP code as the zend engine is. ;)
 

monoVertex

I'm back!
Reaction score
460
Okay, I tested the code and its translated versions into 5 languages: PHP, Pascal, Javascript, Jass and SciTE (the code AutoIt uses).

I must say that the results are... interesting!

Jass was the only one to show A and C. All others show A and B. However, it seems that Javascript and Pascal act really different. In these 2, A is being shown even with an if like this:

PHP:
if( true || true && false )
{
	print 'A';
}

Normally, A should not be printed anymore in this condition. This is my logic explanation. However, Javascript and Pascal DO print A. Based on this, one could say that the && is prioritized. If so, then why isn't the relapse() called in the original code, in these languages?! I mean, if $bool && ! relapse() would be evaluated first, then relapse should be called. However, it was not. That leads me to think that the evaluation actually skips the entire condition after the first 'or'!

Which, I think, it's wrong. That && false is supposed to change the entire output, but it's not even evaluated.

However, in PHP and SciTE, when using that condition, A is not being shown anymore, as it should. Thus, in these 2, the || is not skipped 'blindfolded', it actually checks what is there after it.

Indeed, mind-boggling :p.
 

Xorifelse

I'd love to elaborate about discussions...........
Reaction score
87
Jass was the only one to show A and C. All others show A and B. However, it seems that Javascript and Pascal act really different. In these 2, A is being shown even with an if like this:

PHP:
if( true || true && false )
{
	print 'A';
}

Then I don't want to be the one that breaks your wet pantyhose but A should be printed in a condition like that.

Code:
procedure test;
begin
  if( true or true && false ) then // if ( true or false ), either way execution.
  begin 
    println 'A';
  end;
end.

Eitherway, it should be printed.

That leads me to think that the evaluation actually skips the entire condition after the first 'or'!
That probably because it returned true already, it is either condition being OR condition being true.

Which, I think, it's wrong. That && false is supposed to change the entire output, but it's not even evaluated.

However, in PHP and SciTE, when using that condition, A is not being shown anymore, as it should. Thus, in these 2, the || is not skipped 'blindfolded', it actually checks what is there after it.

Indeed, mind-boggling :p.
Perhaps it better to post those testing scripts because I get a hunch that you scripted it wrong. Perhaps not but there is no way to be sure now.
 

monoVertex

I'm back!
Reaction score
460
Then I don't want to be the one that breaks your wet pantyhose but A should be printed in a condition like that.

Why? I mean, I have been convinced so far that || and && are equal and they are read from left to right. That would mean true || true (which equals true) and then true && false (which equals false).

In math, it's the same. In 10 / 5 x 2 you do the 10/5 first (=2) then 2x2 (=4). If you reverse the order and do 5x2 (=10) then 10/10 you get a whole different result - 1!

My point is that, considering that && and || are equal and the left-to-right rule applies, then A should not be printed.

And I don't understand why you tell me that it should show A anyway :p.

Will post the scripts over about half an hour, as I am in a hurry to go somewhere.



EDIT: I have rewritten them in the 5 langs and it seems I got it wrong with that (true || true && false) in PHP, as it showed A as well, this time. SciTE, however, still did not show it. Anyway, to test that lone condition, I added another if. Here are the 5 script I used (I also attached the files in a .zip).

PHP:
(shows A, B, D)
PHP:
<?

$bool = true;

function relapse()
{
	global $bool;

	return $bool = ! $bool;
}

if( $bool || $bool && ! relapse() )
{
	print 'A';
}
if( $bool )
{	
	print 'B';
} 
else 
{
	print 'C';
}
if( true || true && false)
{
	print 'D';
}

?>


Jass: (I am a bit rusty with Jass, and couldn't find any equivalent for the ! operator, so I just made my own function that returns the opposite value)
(shows A, C)
JASS:
globals
 boolean bool=true
endglobals 

function reverse takes boolean ret returns boolean
 if ret==false then
   return true
 else
   return false
 endif
endfunction 

function relapse takes nothing returns boolean
 set bool=reverse(bool)
 return bool
endfunction

function Trig_Untitled_Trigger_001_Actions takes nothing returns nothing
 if (bool or bool and reverse(relapse()) ) then
  call DisplayTextToForce( GetPlayersAll(), &quot;A&quot; )
 endif

 if bool then
  call DisplayTextToForce( GetPlayersAll(), &quot;B&quot; )
 else
  call DisplayTextToForce( GetPlayersAll(), &quot;C&quot; )
 endif
 
 if (true or true and false) then
  call DisplayTextToForce( GetPlayersAll(), &quot;D&quot; ) 
endif
endfunction



//===========================================================================
function InitTrig_Untitled_Trigger_001 takes nothing returns nothing
    set gg_trg_Untitled_Trigger_001 = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Untitled_Trigger_001, 1.00 )
    call TriggerAddAction( gg_trg_Untitled_Trigger_001, function Trig_Untitled_Trigger_001_Actions )
endfunction



Javascript:
(shows A, B, D)
Code:
<html>

<head>

<title>Javascript</title>

<script type="text/javascript">

var bool=true;

function relapse(){
 return bool=!bool;
}

if( bool || bool && !relapse()){
 alert('A');
}
if(bool){
 alert('B');
} else {
 alert('C');
}
if(true || true && false){
 alert('D');
}

</script>

</head>

<body>

</body>

</html>


Pascal:
(shows A, B, D)
Code:
Program Pascal;
var bool:boolean;

function relapse:boolean;
begin
 bool:=not(bool);
 relapse:=bool;
end;

begin
 bool:=true;
 if (bool or bool and not(relapse)) then
  writeln('A');
 if bool then
  writeln('B')
 else
  writeln('C');
 if (true or true and false) then
  writeln('D');
end.


SciTE:
(shows A, B)
Code:
global $bool=true;

Func relapse()
	return $bool=Not($bool);
EndFunc
	
if($bool or $bool and Not(relapse())) then
	MsgBox(0, "", "A")
endif
if($bool)then
	MsgBox(0, "", "B")	
else
	MsgBox(0, "", "C")
endif
if(true or true and false) Then
	MsgBox(0, "", "D")
endif


Sooooo... it seems that my brain compiles programming codes in the same way as a 7 years old shitty compiler. o_O
 

quraji

zap
Reaction score
144
I did a simpler test with PHP:

PHP:
<?php

function relapse()
{
	echo 'Relapse called<br/>';
    return false;
}

$a = true;
$b = false;

if ($a || $b && relapse())
{
    echo 'True<br/>';
}
else echo 'False<br/>';

?>

It always returns True, with no call to relapse(), unless $a is false, regardless of what $b is. In other words, once it sees that $a is true, and the next operator is an ||, it evaluates the whole expression to true (why would you evaluate the other side of the || unless the first expression were false - it's a waste of time).
It is not reading it as (($a || $b) && relapse()) like someone said! This would result in relapse() being called. It's simply reading it as ($a || ....) where the rest does not matter. This makes sense to me...what is so mind boggling? :p

For the anomalies: JASS evaluates the whole expression, thus resulting in relapse() being called and bool being changed to false. I'm not sure about the SciTE..

By the way, Smith, you can use ! in JASS :D
 

monoVertex

I'm back!
Reaction score
460
It is not reading it as (($a || $b) && relapse()) like someone said! This would result in relapse() being called. It's simply reading it as ($a || ....) where the rest does not matter. This makes sense to me...what is so mind boggling?

[dramatization]Because for others (like me), this inverted my entire reality, as I was convinced it reads it like (($a || $b) && relapse())![/dramatization]

Seriously now, (($a || $b) && relapse()) seems more logical to me, but I already said my mind is like a 7 years old crap compiler xD.

By the way, Smith, you can use ! in JASS

Oh well... It doesn't really matters, as I don't map anymore and the Jass thing was for testing purposes. My reverse() function does the same job as !, anyway.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top