Hi, Am 25.12.2011 um 11:37 schrieb Razvan Rotaru:
> Consider following code: > > (defprotocol WithOptions > (getOptions [this] "All options") > (getOption [this option] "One option")) > > > (defn- gen-proxy [klass opts] > `(proxy [~klass WithOptions] [] > (getOptions [~'_] ~opts) > (getOption [~'this x#] ((getOptions ~'this) x#)))) > > > The gen-proxy functions is a helper which is used in macros. The code > works, as far as I can tell, but there's one thing that intrigues me: > the usage of unquote/quote is necessary (~'_ and ~'this). I assume it > has something to do with macros qualifying symbols with the current > namespace. I am yet to fully understand the mechanism here, but my > question for the moment is whether this kind of construct is idiomatic > in clojure. Or is there another way to introduce symbols in macros? The reason for this is macro hygiene. The ~' is required to introduce a capturing binding into the context of the macro. That is, it shadows a possible this usage in opts. These is usually not what you want and should be avoided. Nevertheless it is possible to do it via ~', which is sufficiently ugly to make you consider whether it's really what you want to do. The normal way to introduce symbols is via the # notation to generate a new symbol, which does not clash with user code. user=> (defmacro oops [& body] `(let [~'murksi 5] ~@body)) #'user/oops user=> (let [murksi 7] (oops (println murksi))) 5 nil BTW: this is implicit in proxy. So you don't have to provide it. (defn- gen-proxy [klass opts] `(proxy [~klass WithOptions] [] (getOptions [] ~opts) (getOption [x#] ((getOptions ~'this) x#)))) Note, how ~'this is still required. That's just one more reason, why you don't want to capture symbols: it makes macro writing harder. Compare to reify: (defn- gen-reify [opts] `(reify WithOptions (getOptions [this#] ~opts) (getOption [this# x#] ((getOptions this#) x#)))) Having this given explicit in the definition makes writing macros simpler. Sincerely Meikel -- 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