Right, of course! It seems almost obvious now :P Thanks Kevin
On Tuesday, March 7, 2017 at 12:42:08 AM UTC+1, red...@gmail.com wrote: > > 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 clo...@googlegroups.com > <javascript:> > > Note that posts from new members are moderated - please be patient with > > your first post. > > To unsubscribe from this group, send email to > > clojure+u...@googlegroups.com <javascript:> > > 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+u...@googlegroups.com <javascript:> > > <mailto:clojure+u...@googlegroups.com <javascript:>>. > > 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.