Ambrose Bonnaire-Sergeant <abonnaireserge...@gmail.com> writes:
> It's a good question.
>
> Syntax quote is designed for generating code/syntax that is deterministic
> and avoids accidental local name capture.
>
> 1. Automatic namespace qualification helps avoid accidental local name
> capture in macros.
>
> user=> `(let [a# 1
>               b# a]
>           a#)
> (clojure.core/let [a__48963__auto__ 1
>                    b__48964__auto__ user/a]
>    a__48963__auto__)
>
> The binding for b# shows a common mistake. By namespace qualifying "a" to
> "user/a",
> we don't allow the possibility of accidentally capturing locals.
>
> eg. "a" is not captured in the body
> (let [a 'evil]
>   (clojure.core/let [a__48963__auto__ 1
>                      b__48964__auto__ user/a]
>      a__48963__auto__))
>


Ah, yes, this makes sense. So, rewriting the macro without the backtick
looks exactly the same, but can capture locals.

(defmacro remap3 [f & c]
  `(map ~f ~@c))

(defmacro remap4 [f & c]
  (list* 'map f c))

(let [map (fn [f & c]
            (println "evil")
            (apply f c))]
  (remap3 identity (range 1 10)))

(let [map (fn [f & c]
            (println "evil")
            (apply f c))]
  (remap4 identity (range 1 10)))


Only the latter is evil.


> 2. Automatic namespace qualification helps make code deterministic with
> respect to the namespace of the consumer of a macro.
>
> Syntax quote resolves vars in the namespace the *macro* is defined in.
> This avoids odd situations where different vars are invoked depending
> on which namespace we use the macro.


Yeah, this was what was confusing me, and was breaking my code. I was
using it to generate code, but not in a macro; my code generates a set
of (specific) Java objects from clojure, and I wanted to be able to
reverse the process -- render clojure forms from Java objects; this
was failing because the symbols were always being qualified in the
namespace of the renderer. In essence, I'm using ` for it's syntactic
convienience, rather than in a macro.


> Bottom line: syntax quote is designed for macros by default. All the good
> properties of syntax quote can be avoided using
> combinations of quote, syntax quote and splice.
>
> eg. `~'a
> ;=> a


I have converted my code to use this! 

Thanks for the explanation. I was confused.

Phil

-- 
-- 
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/groups/opt_out.


Reply via email to