loop

macrosince v0.0-927 clojure.core/loopEdit
(loop bindings & body)

Details:

Evaluates the body-exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs, just like a let form. Acts as a recur target, which will allow tail-call optimization.


Examples:

(loop [x 0]
  (when (< x 10)
    (println x)
    (recur (+ x 2))))
;; Prints:
;; 0
;; 2
;; 4
;; 6
;; 8
;;
;;=> nil

See Also:


Source docstring:
Evaluates the exprs in a lexical context in which the symbols in
the binding-forms are bound to their respective init-exprs or parts
therein. Acts as a recur target.
Source code @ clojurescript:src/main/clojure/cljs/core.cljc
(core/defmacro loop
  [bindings & body]
  (assert-args loop
    (vector? bindings) "a vector for its binding"
    (even? (count bindings)) "an even number of forms in binding vector")
  (core/let [db (destructure bindings)]
    (if (= db bindings)
      `(loop* ~bindings ~@body)
      (core/let [vs (take-nth 2 (drop 1 bindings))
                 bs (take-nth 2 bindings)
                 gs (map (core/fn [b] (if (core/symbol? b) b (gensym))) bs)
                 bfs (reduce (core/fn [ret [b v g]]
                               (if (core/symbol? b)
                                 (conj ret g v)
                                 (conj ret g v b g)))
                       [] (map core/vector bs vs gs))]
        `(let ~bfs
           (loop* ~(vec (interleave gs gs))
             (let ~(vec (interleave bs gs))
               ~@body)))))))