~ / track A / clojure basics

Threading macros

Intermediate

Threading 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:

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

->> inserts the value as the last argument. Useful with sequence operations, because the collection traditionally goes last:

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

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:

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

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.

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate
loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate

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.

loading sci
press ⌘/Ctrl-↵ or click ▶ run to evaluate
 status: new