Postfix, Eager, Translation of Boolean Operators
Eager function argument = argument that is always evaluated in the function
In Java and many programming languages, all function arguments are eager
In Haskell, all function arguments are lazy by default - evaluated only if they are used in the given computation
In Scala, argument is lazy by default if declared with type T, but can be made lazy by declaring them by ⇒ .
For example:
def ifNotE(c : Boolean, s : Unit) : Unit = { if (!c) { s } else { println("Does it pay off to be lazy?") } } var x = 0 IfNot(x==0, 3/x) // division by zero
How to prevent 3/x from being evaluated?
def ifNot(c : Boolean, s : => Unit) : Unit = { if (!c) { s } else { println("Does it pay off to be lazy?") } } IfNotE(x==0, 3/x) // no problem
Bitwise Operators vs Logical Connectives
These are logical connectives, they operate on Booleans:
&& ||
These are bitwise operators:
& |
Example:
10110 & 11011 = 10010
10110 | 11011 = 11111
Note: when the arguments are 0,1 then the truth table is same for && and for &. Similarly, same for || as for |. However, laziness is not the same.
Truth tables:
Compiling Bitwise Operations
[[ e1 & e2 ]] = [[ e1 ]] [[ e2 ]] iand
[[ e1 | e2 ]] = [[ e1 ]] [[ e2 ]] ior
This indeed works for &, | (note: single sign, not && or ||)
Java code:
static boolean test(boolean x, boolean y) { return (x & y); }
static boolean test(boolean, boolean); Code: 0: iload_0 1: iload_1 2: iand 3: ireturn
Effect of Eager Evaluation
Example 1
What does the following Java program do:
class Test { static boolean bigFraction(int x, int y) { return ((y==0) | (x/y > 100)); } public static void main(String[] args) { boolean is = bigFraction(10,0); } }
Answer:
Exception in thread "main" java.lang.ArithmeticException: / by zero at Test.bigFraction(Test.java:4) at Test.main(Test.java:19)
Example 2
What does the following Java program do:
class Test { static int iterate() { int[] a = new int[10]; int i = 0; int res = 0; while ((i < a.length) & (a[i] >= 0)) { i = i + 1; res = res + 1; } return res; } public static void main(String[] args) { System.out.println(iterate()); } }
Answer:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10 at Test.iterate(Test.java:16) at Test.main(Test.java:25)
Lazy Versions of Logical Operators
To enable code patterns similar to above, instead of bitwise operators
| &
we use operators
|| &&
The semantics of Java requires: when evaluating
- (p && q), if p is false, then q is not evaluated
- (p || q), if p is true, then q is not evaluated
This makes sense because of truth tables (expressions have not only truth values, but also side effects):
Because we have explained the evaluation of && and || using 'if', we show first how to compile the conditional expression '?', that is, expression
if (c) then c1 else c2
where c,c1,c2 are all of type Boolean.