On the evaluation axis, what can you no longer conclude from where an expression appears in the text?
answer
- does writing it do it
- position is no longer a schedule
- work happens at the demand site
- never demanded, never produced
- failures surface where the value is used
basics
~20 sWhen - or whether - the work happens. Under deferred evaluation, writing an expression only records how to produce a value; the work runs at the point some other code demands it, which may be far away or never.
solid answer
~40 sThe axis asks a single question: does writing an expression **do** the work, or **record** how to do it. Where writing does the work, position on the page is a schedule, so you can read cost and ordering straight from the text and you guard an expensive call by not reaching it. Where writing records the work, position tells you only where the recipe was made; the computation happens at the point of demand, and a value nothing ever demands costs nothing beyond the record. Two consequences follow directly: cost analysis moves from the definition site to the demand site, and so does any failure inside the expression. Whether a second demand is cheap depends on whether the strategy remembers the first result.
code
pseudocode · 10 linesexpensive = computeReport(allOrders) // does this run here?
if user.wantsReport
show(expensive)
else
show("skipped")
// eager end: the report is computed before the branch is tested
// deferred end: the report is computed only inside the first branch,
// and never at all when the second branch is takengo deeper
Know that in some languages writing an expression performs its work immediately, while in others it only describes work that happens when something asks for the value.
Explain what the text stops telling you under deferral - when the work runs, whether it runs at all, and where a failure appears - and give one reading that detects it from a sample.
Show the operational consequence: cost and failures land on the consumer, and a long-held record retains its unevaluated inputs rather than the small result you expected.
Weigh describing more than you consume against a readable cost model, and say which the team's debugging and capacity practices are actually equipped for.
## The axis in one question The evaluation axis asks whether **writing an expression is doing it**. At the eager end, reaching a line means the work described by that line runs, then and there, exactly once per time you reach it. At the deferred end, reaching the line creates a record of how to produce the value, and the record is turned into a value only when something demands it. This is the axis engineers most often forget is an axis at all, because one position feels like the absence of a choice. It is not: most languages evaluate eagerly and offer deferral as an explicit construct, some defer by default, and a few defer for particular positions such as the branches of a conditional. The score you write on the worksheet is which behaviour the language's ordinary forms give you. ## What stops being readable off the page Under deferral, the text loses four things it told you before: - **When.** The work happens at the demand site, which may be in a different routine, a different module, or a caller you cannot see. - **Whether.** A value nothing demands is never produced. Defining it costs the record and nothing else. - **How often.** A second demand may recompute or may return a remembered result, depending on the strategy the language uses. - **Where a failure appears.** A failure inside the expression surfaces where the value was demanded, not where it was written, so the stack you are given points at the consumer. ## What each end buys and costs | Reading | Writing does the work | Writing records the work | |---|---|---| | A definition nothing consumes | still runs | costs only the record | | Guarding an expensive call | by not reaching the line | by nobody demanding it | | Cost of a line | readable in place | belongs to whoever demands | | Failure location | at the expression | at the demand site | | Defining more than you consume | wasteful or impossible | ordinary | | Holding a record for a long time | not applicable | keeps the unevaluated work, and its inputs, alive | The deferred end buys the ability to describe more than you will use: a structure larger than the part you consume, a fallback that costs nothing while the primary path succeeds, an expensive default that is only produced when the lookup misses. The eager end buys a cost model you can read, and effects that happen where they are written. ## Direction traps worth stating precisely 1. A deferred value is computed **on demand**. If the strategy remembers the result, the *second* demand is cheap - the first one still pays in full. Remembering is not free either: a remembered result is retained as long as the record is. 2. Deferral is **not** the same as the evaluator reordering independent work. That is the control-versus-data-flow axis. A language can defer and still fix the order of everything it does evaluate. 3. Eager evaluation does not mean the language cannot defer at all. Nearly every eager language has some construct for delaying work; the axis records the default, not the ceiling. 4. Deferral does not make a program faster by itself. It removes the cost of work nothing needed and adds bookkeeping to everything else, so the win depends entirely on how much of what you describe is actually demanded. ## Reading the axis from a sample Three readings settle it quickly: 1. **The unused-definition reading.** Define a value whose production would be obviously observable, never consume it, and see whether anything happened. 2. **The failure-location reading.** Put a failing expression in a definition and demand it three calls away. Where does the failure appear - at the definition, or at the demand? 3. **The infinite-description reading.** Can you describe a sequence with no end and consume the first few elements? That is only possible where writing records rather than does. Write the score down as one line: *does writing do it, and if not, is a second demand cheap*. Everything else about the axis - the strategies themselves, the machinery that stores an unevaluated record, and the trade-offs between remembering and recomputing - is the functional-style subject in depth, and the worksheet does not need it. What the worksheet needs is the consequence: on this language, the page is no longer a schedule, and both cost and failure belong to the consumer.
- Why does holding a deferred value for a long time sometimes cost more memory than the value itself?Because the record keeps everything it needs to produce the value alive - the inputs it closed over, and any record those depend on. A small final result can sit behind a chain of unevaluated work that retains large inputs, so the retained footprint is the recipe's, not the result's.
saying these in an interview costs you the question
- Believes a deferred expression runs where it is written
- Says deferred evaluation always makes a program faster
- Thinks a value that is never demanded is still computed
- Assumes an eager language has no way to defer anything
- Assumes every deferral caches, so the second demand is free
- Confuses deferral with the evaluator reordering independent work