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
