liveBook · Manning

For form

As explained in Clojure: The Essential Reference

for is a Clojure macro that generates a lazy sequence by combining collection bindings, optional filtering clauses, and a result body.

for is a Clojure macro for aggregating, filtering, and transforming multiple collections into a lazy sequence. It replaces many nested map–filter compositions without relying on mutation or imperative iteration. A form requires at least one collection binding and a non-empty body. section 3.4.3

Listing 3.20. → Iteration, Sequence Processing, Comprehension, Lazy Sequence Building
(for [seq-exprs body-expr])

Use the compact contract to see the required binding structure and the four permitted binding clauses. section 3.4.3

A for binding vector can contain:

  • Collection bindings such as [name range], where range is any expression convertible to a sequence. section 3.4.3
  • :let bindings for derived local values; bound names remain visible to later clauses and the body. section 3.4.3
  • :when predicates for filtering combinations, including predicates depending on multiple local bindings. section 3.4.3
  • :while predicates for stopping traversal of a binding sequence. section 3.4.3

Filtering and deriving values

(for [i (range 10) [k v] {:a "!" :b "?" :c "$"} :let [s (str i k v)] :while (not= :b k) :when (odd? i)] s) ;; ("1:a!" "3:a!" "5:a!" "7:a!" "9:a!") Multiple bindings generate combinations. For example, matching numbers against squares produces [y x] pairs from [0 0] through [9 81]. section 3.4.3

Laziness and infinite inputs

(take 6 (for [i (range) j (range) :while (< j 3)] (str i j))) ;; ("00" "01" "02" "10" "11" "12") for consumes input sequences lazily, but incompatible constraints can produce a computation that never terminates. section 3.4.3

How Clojure: The Essential Reference covers it

How deep it goes
Defines syntax, evaluation rules, laziness, constraints, and edge cases, while stopping short of a complete macro-expansion treatment.
Examples
Demonstrates map-like combinations, destructuring, :let, :when, :while, infinite ranges, and Conway’s Game of Life neighbor counting.
What you can do after
Apply it to build lazy result sequences from multiple collections with derived values and conditional traversal.
How it connects
Ties list comprehension to lazy sequences, sequence processing, map, filter, let, and range.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.