Extract Variable

Compare
Symptom
Human

A long expression in a conditional, return statement, or method argument that the reader must mentally parse — multiple operations on multiple inputs producing one value. The reader's rises because every read re-parses the full expression to derive its meaning, and debugging requires breakpoints inside the expression to inspect the intermediate value.

Agent

An expression complex enough that the agent parses it sub-step by sub-step to interpret; subsequent reasoning about the value requires re-parsing the full expression. The agent's carries the parsed structure across every reference, and the of any downstream edit compounds because the parse has to be redone at each touch.

Goal
Human

A complex expression earns a name that says what it represents in the domain. Readers resolve to one named token instead of re-evaluating the expression at every use; the binding's definition site is the only place the expression appears, and the named value is reusable in nearby code without restating the calculation.

Agent

Intermediate values carry domain names; subsequent reads resolve to one token of name instead of re-evaluating the expression at every use. The agent's holds the bound name and its definition; the agent's per reference drops to the length of the name, and the binding's definition site is the only place the parse must happen.

Before the refactoring

if (order.qty * order.price - Math.max(0, order.qty - 500) * order.price * 0.05 > 1000) { /* ... */ }

After the refactoring

const basePrice = order.qty * order.price;
const bulkDiscount = Math.max(0, order.qty - 500) * order.price * 0.05;
if (basePrice - bulkDiscount > 1000) { /* ... */ }
Example source: Illustrative example written for this site; the refactoring itself is catalogued in Martin Fowler's Refactoring (Addison-Wesley, 2018), see the chapter on A First Set of Refactorings.
Pressure
Human

Readers pay parsing cost every time; debugging the value requires breakpoints inside the expression; comments scatter to explain what subexpressions mean. The team's compounds across every reviewer who must re-parse the full expression to verify a change, and the same parsing happens at every call site that touches the expression.

Agent

The agent re-parses complex expressions at every reference; debugging requires the agent to mentally evaluate the full subexpression chain. The agent's on each reference site is the cost of re-running the parse, and the agent's rises because verifying behavior requires confirming the parse produced the value the surrounding code assumes.

Tradeoff
Human

Over-extracting tiny expressions clutters scope with one-shot names; extract when the expression carries domain meaning the surrounding code can't speak. The team's can rise rather than drop if extractions don't earn their names, because every binding is one more name the reader must look up and the scope table grows with definitions that document nothing.

Agent

Each extracted variable is a name in the agent's local scope; over-extraction creates scope clutter the agent navigates to find what's actually relevant. The agent's rises during the extraction itself — every use of the original expression must be confirmed to route through the new binding, and stray inline references become a regression.

Relief
Human

Reusable in nearby code; debugging shows the intermediate value; comments explaining the expression become unnecessary. The team's drops because adding a new use of the value is one reference to the existing name rather than restating the full expression, and bugs in the calculation surface at one binding site instead of N call sites.

Agent

Subsequent reads of the value pay one token of name instead of re-evaluating the expression at every use; the binding's definition site is the only place the expression appears. The agent's on downstream edits operates on the name as an opaque token, and verification surface contracts to the binding rather than the expanded calculation.

Trap
Human

Extracting every short expression — including ones already self-explanatory — clutters scope with one-shot names that obscure rather than reveal intent. The of scanning scope to find what each name binds rises faster than the per-expression comprehension cost drops, and the cure adds to scope-table navigation.

Agent

Extracting every sub-expression — including ones already obvious — inflates the agent's scope table with names that document nothing the agent didn't already know. Context-window load rises with one-shot bindings the agent reads to confirm they aren't load-bearing, and the scope-table navigation cost exceeds the per-reference token cost the extraction was meant to save.