Simplify a complex function
Rewrites a hard-to-follow function into a clearer one with identical behaviour, using guard clauses, named steps and simpler conditions, verified by tests. Use on long or deeply nested code.
A function is hard to change when a reader has to hold too much in mind at once: deep nesting, flags that switch behaviour, long stretches doing several jobs, conditions that need a truth table. Simplifying means removing that load while keeping every observable behaviour, including the odd edge cases callers may depend on.
Simplify .
- Read the function and its callers. Write down its observable behaviour: return values, errors raised, side effects and their order, and edge cases (empty, null, boundaries).
- Make sure tests pin that behaviour. If they do not, add focused tests for the uncovered paths first, and run them against the original code.
- Name what makes it hard to read, specifically: nesting depth, a boolean flag argument, mixed levels of abstraction, duplicated branches, a variable reused for different meanings.
- Apply the smallest set of changes that addresses those points. Typical moves:
- guard clauses and early returns instead of nested conditions;
- extract a well-named helper for each distinct step;
- split a flag argument into two functions when the flag selects different behaviour;
- simplify boolean expressions and name complex conditions;
- replace a long if/else chain over one value with a lookup table, when that is clearer.
- Run the tests after each change. Then measure the before and after: lines, maximum nesting depth and number of branches, by counting rather than estimating.
- Behaviour stays identical, including error types and messages, side-effect order and edge-case results. If you believe an edge case is a bug, keep it and report it.
- Do not change the function's signature or public name unless asked.
- Prefer clear over clever: no dense one-liners, no new abstractions with a single use.
- Match the surrounding code's style and idioms.
- Do only what was asked. If you notice something else worth changing, mention it in one line at the end instead of changing it.
- Keep the change as small as it can be while still being correct.
- Before saying the work is done, run the check that proves it (tests, build, type check or the command the user gave) and report the real result.
- If you could not run a check, say so plainly and say which one.
What made it hard
Two to four bullets.
Diff
The diff, including any tests added first.
Behaviour check
The test command and result, and the tests added to pin behaviour.
Before and after
A table: Metric | Before | After, for lines, maximum nesting depth and branches.
1 required value still a placeholder; the assistant will ask for it.
details
- kind
- Prompt: a task you run by name to get one finished thing back
- domain
- Software engineering
- category
- Refactoring
- level
- Beginner
- made for
- Software engineer
- needs
- repo-read, file-write, shell
- risk
- runs-commands
- version
- v1.0.0 · incubating
- reviewed
- 2026-10-02
- works in
- Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Antigravity, OpenCode, Windsurf, Zed, Continue, AGENTS.md
use in
npx @hermes-hq/hodios install simplify-function --target claude-codenpx skills add hermes-hq/hodios-dist --skill simplify-function -a claude-codeclaude plugin marketplace add hermes-hq/hodios-distclaude plugin install hodios-software-engineering@hodiosThe plugin brings every entry in this domain at once.
pairs well with
All of RefactoringAdd characterization tests to legacy code
Pins down what untested legacy code does today with characterization and golden-master tests, bugs included, so it can be changed safely. Use before refactoring or modifying code with no tests.
add-characterization-testsExtract a module
Moves one responsibility out of a large file or class into its own module in small, test-verified steps, without changing behaviour or the public API. Use when a file does too many things.
extract-moduleImprove naming in code
Proposes clearer names for variables, functions, types and modules, explains each rename and applies them without changing behaviour. Use when code reads poorly because of its names.
improve-namingPlan a large refactor in safe steps
Turns a large refactor into small, independently shippable steps that keep the build green, each with a rollback, using patterns like expand-contract. Use for refactors too big for one PR.
plan-large-refactorReduce code duplication
Finds duplicated logic, separates true duplication from code that only looks alike, and merges only true duplicates behind one well-named function. Use when one fix keeps landing in many places.
reduce-duplicationRemove dead code safely
Finds unused code, flags, endpoints, jobs and dependencies, proves each dead with static and runtime evidence, and removes it or stages a reversible retirement. Use to shrink a codebase.
remove-dead-code