# iteration, loops, and recursion this section outlines the main choices when designing loops. recursion, iteration, and higher-order forms like map or fold are interchangeable; the key is understanding when and how to use each based on termination, state, and structure. # design variables each loop construct can be analyzed along the following axes: * termination: how and when the loop stops * explicit condition (e.g. index bound, sentinel value) * implicit in recursion via base case * bounded iteration over structure (e.g. list, range) * state management: what data is updated across iterations * single accumulator (e.g. in fold) * multiple accumulators or local bindings * in-place mutation (imperative) vs structural updates (functional) * composition style: how the loop integrates with surrounding code * inline loop with side effects * returned data structure * higher-order combinators (map, filter, fold) * tail-recursive self-call * control flow abstraction: how much of the control is abstracted * full control: explicit loop or recursion * partial abstraction: fold, unfold, etc. * total abstraction: lazy sequences, generators # common iteration forms * map: applies a function to each element and returns a new structure * one input, one output * no internal state across iterations * fold/reduce: accumulates a result by applying a function across elements * single state variable updated per step * suitable for scalar summarization or structural transformation * unfold: generates a structure from a seed by repeated transformation * inverse of fold * useful for stream generation or constructing lists recursively * custom recursive loop: uses a named recursive binding (e.g. `let loop`) * full control over state and branching * allows multiple outputs and mixed control flows # example: custom recursive map in scheme ```scheme (let loop ((rest (list 1 2 3))) (if (null? rest) rest (cons (+ 1 (car rest)) (loop (cdr rest))))) ``` this implements a basic map operation by: * checking termination via `(null? rest)` * recursively calling `loop` with `(cdr rest)` * producing a new list via `cons` and `(+ 1 ...)` this style generalizes easily - for example, by accumulating additional values, branching conditionally, or logging state. # considerations when designing a loop * identify the stop condition early * in recursion: base case * in loops: compare indices, flags, or structure traversal * determine what state changes per iteration * single or multiple variables * structural updates or in-place mutation * decide how much abstraction is acceptable * simple transformation -> use `map`, `fold` * multi-output or conditional branching → use explicit recursion or `let loop` * consider composition * is the result fed to another transformation? * does the loop perform side effects or produce a return value?