macro | since v0.0-927 | clojure.core/doseq | Edit |
(doseq seq-exprs & body)
Repeatedly executes body
(presumably for side-effects) with bindings and
filtering as provided by for
. Does not retain the head of the sequence.
Returns nil.
Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by "for". Does not retain the head of the sequence. Returns nil.
(core/defmacro doseq
[seq-exprs & body]
(assert-args doseq
(vector? seq-exprs) "a vector for its binding"
(even? (count seq-exprs)) "an even number of forms in binding vector")
(core/let [err (core/fn [& msg] (throw (ex-info (apply core/str msg) {})))
step (core/fn step [recform exprs]
(core/if-not exprs
[true `(do ~@body nil)]
(core/let [k (first exprs)
v (second exprs)
seqsym (gensym "seq__")
recform (if (core/keyword? k) recform `(recur (next ~seqsym) nil 0 0))
steppair (step recform (nnext exprs))
needrec (steppair 0)
subform (steppair 1)]
(core/cond
(= k :let) [needrec `(let ~v ~subform)]
(= k :while) [false `(when ~v
~subform
~@(core/when needrec [recform]))]
(= k :when) [false `(if ~v
(do
~subform
~@(core/when needrec [recform]))
~recform)]
(core/keyword? k) (err "Invalid 'doseq' keyword" k)
:else (core/let [chunksym (with-meta (gensym "chunk__")
{:tag 'not-native})
countsym (gensym "count__")
isym (gensym "i__")
recform-chunk `(recur ~seqsym ~chunksym ~countsym (unchecked-inc ~isym))
steppair-chunk (step recform-chunk (nnext exprs))
subform-chunk (steppair-chunk 1)]
[true `(loop [~seqsym (seq ~v)
~chunksym nil
~countsym 0
~isym 0]
(if (coercive-boolean (< ~isym ~countsym))
(let [~k (-nth ~chunksym ~isym)]
~subform-chunk
~@(core/when needrec [recform-chunk]))
(when-let [~seqsym (seq ~seqsym)]
(if (chunked-seq? ~seqsym)
(let [c# (chunk-first ~seqsym)]
(recur (chunk-rest ~seqsym) c#
(count c#) 0))
(let [~k (first ~seqsym)]
~subform
~@(core/when needrec [recform]))))))])))))]
(nth (step nil (seq seq-exprs)) 1)))