Control flow: early returns, guard clauses, linearizing nested logic. Use for "flatten these conditions", "too many nested ifs", "linearize this try-catch", or handlers mixing throw and return. For a broad "simplify this" pass over a diff or package, use collapse-pass instead.
Control flow: early returns, guard clauses, linearizing nested logic. Use for "flatten these conditions", "too many nested ifs", "linearize this try-catch", or handlers mixing throw and return. For a broad "simplify this" pass over a diff or package, use collapse-pass instead.
metadata
{"author":"epicenter","version":"1.0"}
Human-Readable Control Flow
When refactoring complex control flow, mirror natural human reasoning patterns:
Related Skills: See refactoring for systematic code audit methodology including branch collapsing and caller counting.
Core Pattern
Ask the human question first: "Can I use what I already have?" -> early return for happy path
Assess the situation: "What's my current state and what do I need to do?" -> clear, mutually exclusive conditions
Take action: "Get what I need" -> consolidated logic at the end
Use natural language variables: isUsingNavigator, isUsingLocalTranscription, needsOldFileCleanup: names that read like thoughts
Avoid artificial constructs: No nested conditions that don't match how humans actually think through problems
Transform this: nested conditionals with duplicated logic
Into this: linear flow that mirrors human decision-making
Example: Early Returns with Natural Language Variables
// From packages/epicenter/src/indexes/markdown/markdown-index.ts/**
* This is checking if there's an old filename AND if it's different
* from the new one. It's essentially checking: "has the filename
* changed?" and "do we need to clean up the old file?"
*/const needsOldFileCleanup = oldFilename && oldFilename !== filename;
if (needsOldFileCleanup) {
const oldFilePath = path.join(tableConfig.directory, oldFilename);
awaitdeleteMarkdownFile({ filePath: oldFilePath });
tracking[table.name]!.deleteByFilename({ filename: oldFilename });
}
Example: Linearizing try-catch into Guard + Happy Path
try-catch blocks create a nested, two-branch structure: the try body and the catch body. When only one call inside the try can actually throw, replace the try-catch with a guarded call + early return so the code reads top-to-bottom.
Every guard has the same shape: check → return early on failure. The happy path accumulates at the bottom. Reading top-to-bottom, you see every way the function can fail before you see the success case.