clojure - (gensym) is always unique, `(symb#) is not -- why? -


if write macro uses symb# shortcut create gensym bound global variable, exact same symbol gets generated on , over. however, functions correctly if call gensym manually. simple examples:

(defmacro indirection     [name & body]     `(do (def name# ~@body)          (defn ~name [] name#)))  (indirection foo 3) (foo) ; ⇒ 3 (indirection goo 5) (goo) ; ⇒ 5 (foo) ; ⇒ 5 

the problem apparent if use macroexpand:

(macroexpand '(indirection foo 3)) (do (def name__2863__auto__ 3) (clojure.core/defn foo [] name__2863__auto__)) (macroexpand '(indirection foo 3)) (do (def name__2863__auto__ 3) (clojure.core/defn foo [] name__2863__auto__)) 

this problem goes away if call gensym long way:

(defmacro redirection     [name & body]     (let [rename (gensym)]         `(do (def ~rename ~@body)              (defn ~name [] ~rename))))  (redirection koo 3) (koo) ; ⇒ 3 (redirection moo 5) (moo) ; ⇒ 5 (koo) ; ⇒ 3 

so, why difference? missing?

syntax quoting ` reader macro; form follows transformed reader (which translates text clojure forms) prior evaluation. means symbol ending in # within syntax-quoting translated autogenerated symbol once, when text first read; autogenerated symbol inserted directly macro definition, , appears verbatim in macroexpanion every time macro invoked. can illustrated @ repl:

user=> `(foo bar#) (user/foo bar__2288__auto__) user=> `(foo bar#) (user/foo bar__2291__auto__) 

the typical use case auto-gen'ed symbols # define local variables inside quoted let or fn form. there, not matter same symbol re-used multiple macro invocations; needs unique within each invocation. instance:

(defmacro indirection   [name body]   `(let [name# ~body]      (defn ~name [] name#))) 

Comments

Popular posts from this blog

css - SVG using textPath a symbol not rendering in Firefox -

Java 8 + Maven Javadoc plugin: Error fetching URL -

node.js - How to abort query on demand using Neo4j drivers -