Threading macros
IntermediateThreading macros rewrite a stack of nested calls into a top-to-bottom pipeline.
You write the steps in reading order, and the macro plumbs each result
into the next call as if you'd written (g (f (h x))) by hand. The two most
common are -> ("thread first") and ->> ("thread last").
Minimal example
-> inserts the running value as the first argument of the next form.
Useful when chaining map/struct operations:
->> inserts the value as the last argument. Useful with sequence
operations, because the collection traditionally goes last:
Practical example: choosing the right thread
Pick -> for "I'm transforming a thing" code, and ->> for "I'm transforming
a collection" code. Mixing them in one pipeline usually means you want
as->, which gives the running value an explicit name you can put anywhere:
Conditional threading
some-> short-circuits the moment a step returns nil. cond-> lets you
apply transformations only when a predicate holds. Together they handle the
"optional pipeline" pattern without nested ifs.
Why this matters
- Without threading, the same logic stacks parentheses inside-out, forcing you to read backwards.
- Threading turns a value-transformation pipeline into a sequence of small, inspectable steps — pause anywhere, you know what's in the "wire."
Check yourself
? quiz
When should you prefer `->>` over `->`?
Exercise
Rewrite the nested expression below using ->>. It should compute the sum of
the squares of the odd numbers up to 10.