Lazy evaluation is evaluation by need: an expression is deferred until its value is demanded, and its computed value is shared for subsequent demands of the same suspended computation.
Its two key properties here are avoiding evaluation of unused expressions and sharing demanded computations. For example, the first component of
(3, undefined) can be obtained without evaluating the second. A suspended expression is represented by a thunk; after evaluation its result can be reused. This supports productive infinite lists: take 5 [0..] demands only a finite prefix. It does not guarantee that a demanded computation terminates. Thunk 2026-10-31
A suspended computation together with the information needed to evaluate it later. In lazy evaluation by need, forcing a thunk computes and records its result, so subsequent demands can reuse it. Deferral and memoization are distinct: a merely delayed computation need not share its result unless its evaluation mechanism provides that sharing.