Functions whose body has dozens of lines and a mix of concerns — fetching, calculating, formatting, and logging all interwoven. The reader must hold all of them simultaneously while tracing the path through the body, and the cyclomatic complexity of the function rises with every branching point the procedure has accumulated.
Each function reads as a sequence of named single-responsibility steps; nothing does more than its name advertises. The reader's mental model of each step fits in working memory simultaneously with the others, and separation of concerns is encoded structurally in the function's name and signature rather than buried in its body.
Smellier version
function ship(order) {if (!order.id) throw new Error('missing id');const tax = order.total * 0.1;const grand = order.total + tax;email(order.user, `Total ${grand}`);log(order);}
Fresher version
function ship(order) {validate(order);const grand = withTax(order);notify(order, grand);}
Each line is an opportunity for the reader to lose context; understanding the whole function at once raises cognitive load with every added line. Bugs sneak in where one concern's state collides with another's — and reviewers ship the merge because the function's signature gave them no way to see which lines belonged to which concern.
Splitting introduces a navigation cost — readers gain named outlines but pay function-jump hops to follow the implementation. The wrong granularity buys clutter without comprehension; the right granularity makes the workflow visible at signature level while leaving the per-step logic inside each helper. The team's verification cost drops only when the names earn their keep.
Faster to read, easier to test, simpler to change one step without touching the others. The team's debugging cost drops because the failing concern is named at the call site; each helper's contract is independently testable, so a regression in one step doesn't require re-verifying the whole procedure.
A fan-out of one-line helpers where the workflow can no longer be read linearly — extraction without earning a name introduces accidental complexity by fragmenting the procedure into pieces too small to mean anything. The reader pays the function-jump cost on every line while gaining nothing in comprehension cost.