Working with map, filter, fold, and apply

Build deterministic pipelines from left-to-right collection traversal and keep callback arity and result contexts explicit.

See it run

LISPEX
(reduce + 0 (map (lambda (x) (* x x)) (filter odd? (list 1 2 3 4))))

Observed result

OUTPUT
10

Walk through the pattern

  1. Select. filter keeps 1 and 3 because odd? is true for them.
  2. Transform. map squares the retained values, producing (1 9) in the same order.
  3. Combine. reduce starts at 0 and adds each square, producing 10.

How to reason about it

  • Use map for one result per element, filter for truth-valued selection, and folds for one accumulated result.
  • Use all? or any? when a strict boolean answer can stop the traversal early.
  • Callbacks execute as guest procedures, so errors, escapes, warnings, and value-context rules remain active.
  • string-map and vector-map produce fresh collections; their for-each variants run only for effects and return zero values.
  • Use apply when a final proper list should become positional arguments; it preserves tail application.

Check yourself

Replace odd? with even?. What does the same pipeline return?

Answer

It keeps 2 and 4, squares them to (4 16), and returns 20.

A common mistake

A callback that yields zero or multiple values in a single-value traversal position raises E320.

Keep going

Use the reference for exact callback arities. Use recursion when traversal needs a shape that no maintained combinator expresses clearly.

Higher-order reference · Recursion guide