Strict v.s. Non-Strict

  • Evaluation Order
    • Strict Evaulation: evalulate the arguments, then call the function
    • Non-strict Evaulation: call the function and pass the un-evaluted arguments in (somewhat like strings)
    
                void fun(int x) { print fun, print x }
                int arg() { print arg; return 2; }
                fun(arg());    // Strict eval prints: arg fun 2, 
                               // Non-strict eval prints: fun arg 2
                

Non-strict Evaulation

    Non-strict Evaulation does not ever evaluate arguments it does not use
    
                void fun(int x) { print fun } // doesn't USE x
                int arg() { print arg; return 2; }
                fun(arg());    // Strict eval prints: arg fun 2, 
                // Non-strict eval prints: fun (never uses x, never calls fun)
                

Parameter Passing w/ Non-strict Evaulation

    Why can it memoize?? w/ no side effects, can assume referential transparency; foo(3) always gives same answer.
    
                blah() { print blah }             // w/ side effects
                qux(x,y,z) { return x+y+z }
                qux(blah(), blah(), blah());
                floop(x) { return x+x+x+x+x+x+x }
                floop(blah());
                
    Call by Name prints Call by Need prints
    qux(blah(), blah(), blah()); blah blah blah blah
    floop(blah()); blah blah blah blah blah blah blah

Short circuit

    Do left of boolean op. If answer known, skip doing right. How can we tell? Side effects!!
    
                bar() { print "bar"; return true; } // printing is a side effect
                
    w/ short circuit w/o short circuit
    true and bar() Must run right anyway, bar Must run right anyway, bar
    false and bar() silence bar
    true or bar() silence bar
    false or bar() Must run right anyway, bar Must run right anyway, bar
    Watch out | and & are NOT boolean ops. Short circuit is NOT relevant to them!