Skip to content

clojure.core/for

View this page on ClojureDocs

Type: macro Added: Clojure 1.0 Examples: 19 Runnable: 14
([seq-exprs body-expr])

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

by nipra on
by Jacolyte on
by james on
by james on
by alimoeeny on
by huahaiy on
by Dimagog on . May have evaluation errors.
by bzhou on
by jafingerhut on . May have evaluation errors.
by jafingerhut on . May have evaluation errors.
by octopusgrabbus on . May have evaluation errors.
by m-combinator on
by colorgmi on
by abhilater on
by cuspymd on
by jr0cket on . May have evaluation errors.
by vipermark7 on
by jimka2001 on
by ottonascarella on

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


Content from the matching ClojureDocs page, with authors credited on each contribution.