
On Nov 18, 2007 9:23 AM, Paul Johnson
Obviously there is a strong correspondance between a thunk and a partly-evaluated expression. Hence in most cases the terms "lazy" and "non-strict" are synonyms. But not quite. For instance you could imagine an evaluation engine on highly parallel hardware that fires off sub-expression evaluation eagerly, but then throws away results that are not needed.
I've mostly seen "lazy evaluation" used for the strategy where thunks
are only evaluated once.
Consider the function "f x = g x x" and the code "f (a + b)". Because
Haskell is lazy, it only evaluates "a + b" once, even though "f (a +
b)" reduces to "g (a + b) (a + b)".
In Haskell, the only difference between "f (a + b)" and "g (a + b) (a
+ b)" is efficiency, but there are languages that have non-strict
functions and side-effects. In Algol, IIRC, you could define function
parameters to be call-by-name. A function call like "f(inc(y))" would
not evaluate "inc(y)" until f used its parameter, but it would
evaluate it again each time.
The difference between call-by-name and laziness (aka call-by-need) is
analogous to the difference between these monadic functions:
f1 m = m >>= \x -> g x x
f2 m = m >>= \x1 -> m >>= \x2 -> g x1 x2
--
Dave Menendez