Saturday, March 15, 2008

Logic operators: Lazyness C++, Perl, Java, Javascript, ksh

Examples demonstrating lazy evaluation for || and && in different languages presented.

Consider following c++ code:


Fun1() || Fun2() || Fun3();
Fun1() && Fun2() && Fun3();


In c++, they are executed, only if the result of overall execution depends from execution of function that was not yet executed. '&&' , '||' and ',' are only c++ operators, thats order is direct from left-to right.

In examples:

Java1.6:
/**
* @author rtg
*
*/
public final class main {
public static boolean fun1(){System.out.println("fun1"); return true;}
public static boolean fun2(){System.out.println("fun2"); return false;}
public static boolean fun3(){System.out.println("fun3"); return true;}
/**
* @param args
*/
public static void main (String[] args) {
boolean res;
System.out.println("|| test:");
res = fun1() || fun2() || fun3();
System.out.printf("res:%b\n",res);
System.out.println("&& test:");
res = fun1() && fun2() && fun3();
System.out.printf("res:%b",res);
}
}


Results are the same as for

Javascript in firefox 2 is lazy too:
example

Perl's operators are lazy too:

$ cat lazy_or.pl
#!/usr/bin/perl

sub fun1 {print "fun1\n"; return 1;};
sub fun2 {print "fun2\n"; return 0;};
sub fun3 {print "fun3\n"; return 1;};

sub main
{
print "or:\n";
print "res=" . (fun1() or fun2() or fun3()) . "\n";
print "and:\n";
print "res=" . (fun1() and fun2() and fun3()) . "\n";
print "&&:\n";
print "res=" . (fun1() && fun2() && fun3()) . "\n";
print "||:\n";
print "res=" . (fun1() || fun2() || fun3()) . "\n";
}

main();

rtg@kubic-roman:~$ perl lazy_or.pl
or:
fun1
res=1
and:
fun1
fun2
res=0
&&:
fun1
fun2
res=0
||:
fun1
res=1
rtg@kubic-roman:~$ perl -v

This is perl, v5.8.8 built for i486-linux-gnu-thread-multi


ksh example at the end is different in results from perl c++ and javascript.
After ksh testing I understand, why Java not accepts int's as booleans for the operator.

ksh interprets 0 as true and 1 as false, so it is the place were you have to be patient,
when swith to:

$ cat lazy.ksh
#!/usr/bin/ksh

fun1() {
echo "fun1"
return 1;
}

fun2() {
echo "fun2"
return 0;
}

fun3() {
echo "fun3"
return 1;
}

status(){
echo $?
}

fun1 || fun2 || fun3
status
fun1 && fun2 && fun3
status
rtg@kubic-roman:~$ ./lazy.ksh
fun1
fun2
0
fun1
1


Thats strange, that a lot of programmers in presented languages where very confident about non-laziness of the operators.
However, it is common for all presented languages, and it is no conceptual difference in these languages at the point described.

C++ example:
#include 

int fun1(){std::cout << "fun1\n"; return 1;}
int fun2(){std::cout << "fun2\n"; return 0;}
int fun3(){std::cout << "fun3\n"; return 1;}

int main()
{
int test_val;
std::cout << "\n || test:\n";
test_val = fun1() || fun2() || fun3();
std::cout << "result is:" << test_val << std::endl;
std::cout << "\n && test:\n";
test_val = fun1() && fun2() && fun3();
std::cout << "result is:" << test_val << std::endl;
}
result of code execution is:

|| test:
fun1
result is:1

&& test:
fun1
fun2
result is:0

No comments: