Skip to content

Instantly share code, notes, and snippets.

@jfacorro
Last active March 6, 2017 23:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jfacorro/b07880c04ea9ff110e0be1926dc3d6ca to your computer and use it in GitHub Desktop.
Save jfacorro/b07880c04ea9ff110e0be1926dc3d6ca to your computer and use it in GitHub Desktop.
loop macro, wrapping let
(require '[clojure.walk :as walk])
(walk/macroexpand-all '(loop [[x & xs] xs a 3]))
(let* [G__1249 xs
vec__1250 G__1249
x (clojure.core/nth vec__1250 0 nil)
xs (clojure.core/nthnext vec__1250 1)
a 3]
(loop* [G__1249 G__1249 a a]
(let* [vec__1251 G__1249
x (clojure.core/nth vec__1251 0 nil)
xs (clojure.core/nthnext vec__1251 1)
a a])))
(loop* [G__1249 xs a a]
(let* [vec__1251 G__1249
x (clojure.core/nth vec__1251 0 nil)
xs (clojure.core/nthnext vec__1251 1)
a a]))
(defmacro loop
"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."
{:added "1.0", :special-form true, :forms '[(loop [bindings*] exprs*)]}
[bindings & body]
(assert-args
(vector? bindings) "a vector for its binding"
(even? (count bindings)) "an even number of forms in binding vector")
(let [db (destructure bindings)]
(if (= db bindings)
`(loop* ~bindings ~@body)
(let [vs (take-nth 2 (drop 1 bindings))
bs (take-nth 2 bindings)
gs (map (fn [b] (if (symbol? b) b (gensym))) bs)]
`(loop* ~(vec (interleave gs vs))
(let ~(vec (interleave bs gs))
~@body))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment