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

Reply via email to