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 [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected]
> <mailto:[email protected]>.
> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.