clojure.core/for¶
List comprehension. Takes a vector of one or more binding-form/collection-expr pairs, each followed by zero or more modifiers, and yields a lazy sequence of evaluations of expr. Collections are iterated in a nested fashion, rightmost fastest, and nested coll-exprs can refer to bindings created in prior binding-forms. Supported modifiers are: :let [binding-form expr ...], :while test, :when test.
(take 100 (for [x (range 100000000) y (range 1000000) :while (< y x)] [x y]))
Examples¶
Note by Jacolyte¶
My English parser was choking on the description of this function.
This SO question has helped clarify how this function works.
Note by juergenhoetzel¶
Example 1 can be rewritten without using the for macro. Pure functional should be preferred if possible:
(filter even? (map (partial * 3) [0 1 2 3 4 5]))
Note by shockbob¶
On juergenhoetzel's comment:
All the examples could be re-written in some combination of map and filter, but they are still valid examples of using the for comprehension, AFAIK:
Examples:
user=> (mapcat (fn [e] (map (fn [x] (* x e)) [1 2 3])) [1 2 3]) (1 2 3 2 4 6 3 6 9) user=> (mapcat (fn [e] (map (fn [x] [e x]) [1 2 3])) ['a 'b 'c]) ([a 1] [a 2] [a 3] [b 1] [b 2] [b 3] [c 1] [c 2] [c 3]) user=> (map (fn [e] [e (* e e)(* e e e)]) (range 1 6)) ([1 1 1] [2 4 8] [3 9 27] [4 16 64] [5 25 125]) user=> (map (fn [e] (* e e)) (range 3 7)) (9 16 25 36) user=> (map first (filter (fn [[x y]] (= y 0)) '([:a 1] [:b 2] [:c 0]))) (:c) user=>
Note by csmotricz¶
Take careful note of the description's wording:
binding-form/collection-expr pairs,
each followed by zero or more modifiers
A consequence is that the binding list may not begin with a modifier, i.e a :let, :when or :while!
The following example is illegal syntax:
(for [:let [a 1] b (range 5)]
{a b})
While it might sometimes be convenient to start a for with a :let to reduce code clutter, the "correct" procedure is to nest the for in a "proper" let, like this:
(let [a 1]
(for [b (range 5)]
{a b}))
Similarly, a :when is better represented by nesting in an if.
Note by Joan Charmant¶
The fifth example should probably be shown in first position, it's the most straightforward and readable for a beginner :
(for [x (range 3 7)] (* x x))
Note by Thumbnail¶
"Sequence comprehension", not "list comprehension".
See also¶
- clojure.core/doseq (9)
- clojure.core/doall (0)
- clojure.core/recur (9)
- clojure.core/range (4)
- clojure.core/let (7)
- clojure.core/when (3)
Content from the matching ClojureDocs page, with authors credited on each contribution.