On 03/06/2017 03:28 PM, juan.facorro wrote: > While I was debugging some code I found something related to the *loop > *macro that I found curious. I'm probably missing something but here it > goes. > > The expression generated by the *loop* macro includes a wrapping *let > *when there is any de-structuring in the bindings. > > (require '[clojure.walk :as walk]) > (walk/macroexpand-all '(loop [[x & xs] xs a 3]))
The init value of `a` could rely on `x` or `xs`, so those bindings need to be established before the loop, which is what the outer loop does. For example checkout `(walk/macroexpand-all '(loop [[x & xs] xs a x]))`. > > Which returns: > > > (let*[G__1249xsvec__1250G__1249x(clojure.core/nthvec__12500nil) > xs(clojure.core/nthnextvec__12501) a3] (loop*[G__1249G__1249a a] > (let*[vec__1251G__1249x(clojure.core/nthvec__12510nil) > xs(clojure.core/nthnextvec__12511) aa]))) > > > Since all bindings get re-defined in the inner *let*, why is the outer > *let* even generated? Is there a reason for not having the following > generated instead? > > > (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])) > > > The change in the loop macro is pretty simple and it seems to work (at > least with the tests available in GitHub's clojure/clojure). > > > (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)))))) > > > But maybe this hasn't been changed because of the importance of the > *loop* macro, or maybe the impact in compile- and run-time is > insignificant to justify the change. > > Anyways... I thought I'd put the question out there. > > > Cheers! > > Juan > > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send > an email to clojure+unsubscr...@googlegroups.com > <mailto:clojure+unsubscr...@googlegroups.com>. > For more options, visit https://groups.google.com/d/optout. -- And what is good, Phaedrus, And what is not good— Need we ask anyone to tell us these things? -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.