Skip to main content

Evaluation Order, Aliases, and Observation Boundaries

What This Concept Is​

A structural transformation preserves behavior only relative to an input domain and a set of observations. Return values alone omit exceptions, mutation, input consumption and collaborator calls. State which observations callers may rely on before comparing implementations.

Why It Matters Here​

A callback can mutate state or fail. A getter can read a changing value. Moving either across a loop or a validation boundary can change real behavior even when a happy-path number stays equal.

Concrete Example​

Consider two callbacks A and B. A records "A" and returns true; B records "B" and raises. Sequential guards returning the same value stop after A. A short-circuit OR also stops there. Passing A() and B() into an eager helper evaluates B before the helper runs, so it raises instead.

The invoice's trace is header write, row reads, one clock read, total write. If the second row fails, the header already exists and the clock is not read. Buffering all output first would be a sensible different contract, but not this refactor.

Common Confusion / Misconception​

Immutability of an outer collection does not freeze nested values. Passing an object instead of two numbers can also delay the reads. Likewise, caching a repeated getter can reduce its call count. None of these moves is universally unsafe; each needs the right domain assumptions.

How To Use It​

List the observable events in order. For each extraction, check free variables, assignments, aliases, early returns, exception handlers and iterator lifetime. Preserve the original traversal while extracting; optimize it in a separately checked step.

Check Yourself​

Why does helper(A(), B()) differ from A() or B()? Which invoice observations survive when iteration fails?

Mini Drill or Application​

Write two recording predicates and a generator that fails after one row. Predict the complete trace before running L1 and L2. Feedback: the untaken predicate must not run, and the invoice header remains after an input failure.

Read This Only If Stuck​

Use the Refactoring book index for small-step discipline and the reading guide for supporting primary documentation. Continue with the contracts and labs.