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.
Edge cases bail out early at the top of the function; the main flow is unindented and tells the happy path linearly.
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);}
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.
If multiple paths share work, premature returns can duplicate that work — extract first, then guard.
Indentation drops; the dominant case is obvious; new edge cases land at the top without disturbing the rest.
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.