using-recursion-and-lazinesslisted
Install: claude install-skill yutna/functional-design-skills
# Using Recursion and Laziness
## Overview
Recursion replaces the loop when a computation is defined in terms of
itself, and it is the natural way to consume the recursive types a domain
model produces. Laziness delays a computation until its result is needed,
which turns infinite sequences into ordinary values and lets a pipeline
process more data than fits in memory.
Both are mechanics rather than design principles, but getting them wrong
produces the two most common runtime failures in functional code: a stack
that overflows on real data, and a computation repeated a thousand times
because nobody noticed it was not cached.
## When to use
- Consuming a tree, an expression, or any recursive type
- A stack overflow on input larger than the test data
- The same pure computation runs repeatedly with the same arguments
- A collection is too large to hold in memory
- Generating a sequence with no natural end
Not for: reducing a collection to a value, which is
[folding-over-data](../folding-over-data/SKILL.md).
## Core rules
1. **Write the base case first.** Then the recursive case, and check that
it always moves towards the base.
2. **Make the recursive call the last thing.** A tail call can be turned
into a loop; a call whose result is then modified cannot.
3. **Know whether your language eliminates tail calls.** If it does not,
bound the depth, use an explicit accumulator loop, or trampoline.
4. **Prefer an existing traversal.** Fold, map, and unfold cover most