Section 24
Lazy evaluation and thunks

Normal order / Lazy evaluation

OK, what else can we do? Consider how we go about defining functions. When we say something like

fun sqr(z:int):int = z*z

our intent is that everywhere we write sqr(WHATEVER) we might as well have written WHATEVER*WHATEVER.

This concept is known as referential transparency, and is the key to designing large programs. Functional languages come pretty close to doing this.

However, they don't quite do it. For example consider the following example:

let
  val x:int = 3 
  fun ford(u: int, v: int): int = u + x 
in 
  ford(4, raise Fail "banana") 
end

To solve this issues we will introduce "near" ML languages that use lazy evaluation instead of eager evaluation.

The key notion is a thunk, which is basically a promise to evaluate some expression later on (when it is needed). This is referred to as forcing a thunk. A thunk will be a new kind of value.

Thunks will be created when we apply a function to its arguments. We will create thunks for all the arguments, promising to evaluate them (in the current environment) later on, when and if they are actually needed.

When are thunks forced? Well, when their value is actually needed. But that is actually a tricky question.

Some cases are simple. if, for example, or andalso or orelse, force one argument and depending on its value force some others. Simple primitives, like +, force both/all their arguments.

But there are some real subtleties here.

Consider the expression (fn(x)=>x)(42). This will give us (what?) a thunk. So clearly the top-level loop needs to force its arguments.

Now consider the expression (fn(x)=>x) ((fn(y)=>y)(42)). What happens when we force the thunk? We get another thunk, unless we are careful.

The solution is to define forcing a thunk to force its value repeatedly, until we get a (non-thunk) value.

Also, what about function application? When we see e1(e2) we clearly need to force e1, otherwise we have no idea what to do with e2.

Should :: be lazy or not? ... next time, streams