Replace Nested Conditional with Guard Clauses

Removes smells
Compare
Symptom
Human

Functions with deeply nested if/else where the happy path is buried inside multiple levels of indentation, and edge cases are conditionals around the main flow.

Agent

A function with deeply nested if/else where the happy path is buried under indentation; the agent must trace through edge-case branches to find the main flow.

Goal
Human

Edge cases bail out early at the top of the function; the main flow is unindented and tells the happy path linearly.

Agent

Edge cases exit at the top of the function; the happy path runs at the function's base indent level, and adding a precondition is one new guard at the top instead of a rewrite of the nested branches.

Before the refactoring

function payAmount(employee) {
if (employee.isSeparated) {
return separationPay(employee);
} else {
if (employee.isRetired) {
return retirementPay(employee);
} else {
return regularPay(employee);
}
}
}

After the refactoring

function payAmount(employee) {
if (employee.isSeparated) return separationPay(employee);
if (employee.isRetired) return retirementPay(employee);
return regularPay(employee);
}
Example source: Illustrative example written for this site, not a quotation from any source.
Pressure
Human

The dominant case is hidden under indentation; readers must trace down through edge-case branches to find the main flow; new edge cases extend an already-tangled structure.

Agent

The agent's parsing of the function's intent is obscured by indentation; reasoning about the happy path requires tracking which edge cases have already been ruled out.

Tradeoff
Human

If multiple paths share work, premature returns can duplicate that work — extract first, then guard.

Agent

Early returns can duplicate work if multiple paths share follow-up logic; the agent inlining guards must verify the shared work is genuinely separable.

Relief
Human

Indentation drops; the dominant case is obvious; new edge cases land at the top without disturbing the rest.

Agent

Guards exit at the top of the function and the happy path runs at the function's base indent level; adding a precondition is one new guard prepended at the top instead of a rewrite of the nested branches.

Trap
Human

Inlining guard clauses for every condition — including ones where the edge case shares work with the main path; the early returns duplicate work the structure was sharing.

Agent

Inlining guards for every condition — including ones that shared follow-up work — fragments the shared logic across early-return branches the agent must keep consistent.