Suppose we wish to compute the value of "x+y" in a lazy functional programming language such as Haskell or Nero. This is done with the functional expression
(+ x y). However, if the value of
nil or perhaps unknown in the current context, this expression will segfault. Furthermore, the operation
+ may be expensive, for example if it represents string concatenation. Therefore, it is useful to wrap the computation in a lambda, like so:
(if (nor (isNil x) (isNil y)) (+ x y) else (yield)). This "wrapping" process is referred to in the literature as "ification", since a lambda is fundamentally equivalent to an
if in functional languages.
Ification (a special case of lambda lifting) prevents the premature evaluation of the wrapped computation. However, it doesn't do anything to ensure lazy computation — that is, the computation might be evaluated safely but unnecessarily. Therefore, a second lambda is placed around the computation, this time to ensure that the computation is never performed until and unless it absolutely needs to be. This second lambda-lifting step is performed quietly behind the scenes in lazy languages such as Nero, but conceptually it looks like this:
(if (result_requested) if (nor (isNil x) (isNil y)) (+ x y) else2 (yield)). This second step is referred to as "reification", and it is where lazy languages like Haskell derive most of their power.