for

macrosince v0.0-927 clojure.core/forEdit
(for seq-exprs body-expr)

Details:

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.


See Also:


Source docstring:
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]))
Source code @ clojurescript:src/main/clojure/cljs/core.cljc
(core/defmacro for
  [seq-exprs body-expr]
  (assert-args for
    (vector? seq-exprs) "a vector for its binding"
    (even? (count seq-exprs)) "an even number of forms in binding vector")
  (core/let [to-groups (core/fn [seq-exprs]
                         (reduce (core/fn [groups [k v]]
                                   (if (core/keyword? k)
                                     (conj (pop groups) (conj (peek groups) [k v]))
                                     (conj groups [k v])))
                           [] (partition 2 seq-exprs)))
             err (core/fn [& msg] (throw (ex-info (apply core/str msg) {})))
             emit-bind (core/fn emit-bind [[[bind expr & mod-pairs]
                                       & [[_ next-expr] :as next-groups]]]
                         (core/let [giter (gensym "iter__")
                                    gxs (gensym "s__")
                                    do-mod (core/fn do-mod [[[k v :as pair] & etc]]
                                             (core/cond
                                               (= k :let) `(let ~v ~(do-mod etc))
                                               (= k :while) `(when ~v ~(do-mod etc))
                                               (= k :when) `(if ~v
                                                              ~(do-mod etc)
                                                              (recur (rest ~gxs)))
                                               (core/keyword? k) (err "Invalid 'for' keyword " k)
                                               next-groups
                                               `(let [iterys# ~(emit-bind next-groups)
                                                      fs# (seq (iterys# ~next-expr))]
                                                  (if fs#
                                                    (concat fs# (~giter (rest ~gxs)))
                                                    (recur (rest ~gxs))))
                                               :else `(cons ~body-expr
                                                        (~giter (rest ~gxs)))))]
                           (if next-groups
                             #_ "not the inner-most loop"
                             `(fn ~giter [~gxs]
                                (lazy-seq
                                  (loop [~gxs ~gxs]
                                    (when-first [~bind ~gxs]
                                      ~(do-mod mod-pairs)))))
                             #_"inner-most loop"
                             (core/let [gi (gensym "i__")
                                        gb (gensym "b__")
                                        do-cmod (core/fn do-cmod [[[k v :as pair] & etc]]
                                                  (core/cond
                                                    (= k :let) `(let ~v ~(do-cmod etc))
                                                    (= k :while) `(when ~v ~(do-cmod etc))
                                                    (= k :when) `(if ~v
                                                                   ~(do-cmod etc)
                                                                   (recur
                                                                     (unchecked-inc ~gi)))
                                                    (core/keyword? k)
                                                    (err "Invalid 'for' keyword " k)
                                                    :else
                                                    `(do (chunk-append ~gb ~body-expr)
                                                         (recur (unchecked-inc ~gi)))))]
                               `(fn ~giter [~gxs]
                                  (lazy-seq
                                    (loop [~gxs ~gxs]
                                      (when-let [~gxs (seq ~gxs)]
                                        (if (chunked-seq? ~gxs)
                                          (let [c# ^not-native (chunk-first ~gxs)
                                                size# (count c#)
                                                ~gb (chunk-buffer size#)]
                                            (if (coercive-boolean
                                                  (loop [~gi 0]
                                                    (if (< ~gi size#)
                                                      (let [~bind (-nth c# ~gi)]
                                                        ~(do-cmod mod-pairs))
                                                      true)))
                                              (chunk-cons
                                                (chunk ~gb)
                                                (~giter (chunk-rest ~gxs)))
                                              (chunk-cons (chunk ~gb) nil)))
                                          (let [~bind (first ~gxs)]
                                            ~(do-mod mod-pairs)))))))))))]
    `(let [iter# ~(emit-bind (to-groups seq-exprs))]
       (iter# ~(second seq-exprs)))))