Skip to content

Tensions in Practice: Avoided computation in tension with demand-time latency

Optional computation · downstream demand

A program can compute a value when its inputs become available, or retain a recipe and wait until someone asks for the result. Computing early pays even when nobody asks. Waiting avoids that unused work, but if demand arrives the consumer may have to wait for the computation. Deferral changes which moment bears the cost.

Avoid unused work

Do not compute a result that no downstream consumer ever requests.

Answer promptly at demand

Have a needed result available when the consumer asks for it.

Why these aims pull against each other

Removing computation from the initial path can put it directly on the later response path. Whether that move helps depends on both demand probability and the cost of waiting at demand.

Compare the arrangements

Compute up front

Compute as soon as inputs are ready and retain the result for possible later use.

What it protects
When demand arrives after completion, no deferred computation remains on that response path.
What it costs
The work is paid even if the value is never used, and the result may occupy storage.
When it fits
Fits results likely to be requested soon or a response context that cannot tolerate computation on demand.

Illustration note: The picture assumes the early computation has finished before demand and that its inputs remain valid. It is not a latency guarantee for earlier demand.

Wait for demand

Store a deferred specification; execute only on downstream demand and retain the produced result for reuse.

What it protects
The no-demand branch avoids the computation entirely.
What it costs
The first consumer pays force-time latency, and the deferred specification itself consumes bookkeeping and possibly retained inputs.
When it fits
Fits work often left unused and consumers able to tolerate the first-demand wait.

Illustration note: The right branch means demand never occurs; it is not a timeout that automatically executes the recipe later.

What this illustration does—and does not—establish

Lazy Evaluation: Specify-Time versus Force-Time Latency supplies the temporal tradeoff. Core explicitly supplies both the unused-work saving and bookkeeping cost, so neither option is a cost-free default.

  • Both sketches assume a valid stable computation; side effects, changing inputs and concurrent forcing need additional contracts.
  • Lazy evaluation is not merely caching a value that was already computed or scheduling work to run later regardless of demand.

Source entries

Lazy Evaluation

Prime · Source of the tension

Lazy Evaluation: Specify-Time versus Force-Time Latency supplies the conflict examined here.

Specify-Time versus Force-Time Latency

T2 — Specify-Time versus Force-Time Latency. Decoupling specification from execution moves cost off the up-front path and onto the moment demand fires — but that moment may not tolerate the wait. The tension is temporal: deferral smooths or eliminates up-front cost at the price of latency precisely when the result is finally needed. The failure mode is a force-time execution landing in a latency-critical context (a user-facing request forcing a deep thunk chain), turning saved up-front work into an unacceptable stall. Diagnostic: ask whether the context at force-time can absorb the deferred work's latency; if not, pre-force or move toward eager.

Read the source section

Core Idea

Lazy evaluation pays a small bookkeeping cost — the deferred specification must be held and tracked — in exchange for potentially saving the much larger cost of work never demanded, plus the optionality of doing the work later with better information. Eager evaluation pays the full computation cost immediately to avoid bookkeeping and to have results ready the instant they are asked for. Neither dominates; which is right depends on how often the work is demanded, how costly the wait at force-time is, and how much the intervening information improves the deferred work.

Read the source section