Demand drives computation
A program can represent a calculation before actually performing it, advancing only when another step needs its result. Values belonging to unused paths may never be evaluated. Laziness changes the arrangement of work while preserving the language’s semantics; a large expression does not imply that every component immediately executes.
References: [1]
Delay and sharing
Call-by-need implementations commonly retain a delayed expression, evaluate it on demand, and share the completed result. This differs from repeatedly reevaluating an expression whenever it is used. Forcing, result caching, and exception behavior depend on the language or interface and determine what repeated access actually does.
References: [2]
Consuming data incrementally
A sequence can produce elements incrementally rather than preparing them all in advance. A consumer taking a prefix may never trigger the remaining work, allowing a finite definition to describe an indefinitely extensible sequence. Each requested portion must still be productive; demanding the first element can otherwise fail to make progress.
References: [1]
Time and space tradeoffs
Delaying unused work can save time but requires retaining suspended computations and results. References can keep earlier sequence portions alive after their useful consumption. Programs may force selected values or release references to balance latency and space. The benefit of laziness depends on the actual pattern in which results are requested and retained.
References: [2]