(* Call by Value ------------- ml uses "call by value". What does this mean? Well, when we make a call to some function f(E), ml will evaluate all the arguments before it actually calls f. Consider the following function: *) fun cond (p,e1,e2) = if p then e1 else e2; (* We might think of a call to cond(p,e1,e2) as being equivalent to "if p then e1 else e2". But is it? Lets define a factorial function f using cond *) fun f n = cond(n=0,1,n*f(n-1)); (* f 2 => cond(false,1,2*f(1)) => cond(false,1,2*cond(false,1,1*f(0))) => cond(false,1,2*cond(false,1,1*cond(true,1,0*(f-1)))) : : Recursion does not stop! NOTE: conditional expressions, and boolean operators CANNOT be functions within ml. What we would require is something other than "call by value". Call by Name ------------ To compute the value of cond(p,e1,e2), substitute p, e1, and e2 into the body of the function cond. Then compute the value of the resulting expression. f 2 => cond(2=0,1,2*f(2-1)) => cond(2=0,1,2*cond(1=0,1,1*f(1-1))) => cond(2=0,1,2*cond(1=0,1,1*cond(0=0,1,f(0-1)))) => cond(2=0,1,2*cond(1=0,1,1*1)) => cond(2=0,1,2*1) => 2*1 => 2 Call by Need ------------ Lazy evaluation (aka "call by need") *)