Delayed Evaluation

Delayed, or Lazy, evaluation is the evaluation of the expression only when needed. It is often considered in relation to the arguments to a function call, the idea being that the arguments would not be evaluated until their values are needed. Some languages like Haskell promote this idea to every location, even allowing infinitely long lists that are only evaluated up to where they are needed.

There are two important features needed for delayed evaluation:

In OCAML we can “emulate” this behavior using variant types, references and mutation, and the fact that expression are regular values, as follows:

Here’s how the whole code might look like:

type 'a result = Delayed of unit -> 'a | Evaled of 'a | Raised of exn
type 'a lazy = 'a result ref

(* val delay : (unit -> 'a) -> 'a lazy *)
let delay th = ref (Delayed th)

(*val force : 'a lazy -> 'a *)
let force r = match !r with
  | Evaled v -> v
  | Raised ex -> raise ex
  | Delayed th -> try let v = th ()
                      in (r := Evaled v; v)
                  with ex -> (r := Raised ex; raise ex)

Every time we want to delay an evaluation, and express the fact, we wrap it using the delay function. When we want to get the value out, we use force.