You need to be careful when using syntax-quote (backtick `):
It tries to resolve every symbol it encloses, as the compiler would:
If it's use'd, the symbol is qualified with the origin ns, otherwise
with the current ns (current during read time of the syntax-quote
form, i.e. macro _definition_ time). That's basically the magic that
allows us to have a lisp-1 and still not need to declare functions as
available during compilation or other idiosyncrasies of some scheme
implementations.

Regardless, to introduce a lexical binding in macro expansion code, we
need to make sure that the introduced name never clashes with
macro-user code, a concept known as macro hygiene. The way to do that
in clojure are (auto-)gensyms.
e.g. (defmacro x [of] `(let [name# (expr ..)] (usage ~of name#))
when you try `(let [name (expr)] ...) the compiler complains "Cannot
let qualified name current-ns/name". That's because name got
namespace-qualified, and subsequently can't be let.

In your case, the actual expansion is: (defrecord ... (do-sth
[some-ns/this] some-ns/this), you can check that with (macroexpand
'(my-defrecord R [content])), btw.
In case of a protocol function, the introduction of a ns-qualified
local only seems to be caught in the body (ticket?). I guess that's
because the parameter gets name-mangled.

Anyways, fix is to always use auto-gensyms when introducing lexical
bindings in a macro:

(defmacro my-defrecord [name [& fields] & body]
  `(defrecord ~name ~fields
     MyProtocol
     (do-something [this#] this#)
     ~@body))

If you ever _really_ need to introduce a verbatim name in macro code
(magic names, like 'this' in java, e.g.) you can use

(defmacro my-defrecord [name [& fields] & body]
  `(defrecord ~name ~fields
     MyProtocol
     (do-something [~'this] ~'this)
     ~@body))

Don't do this.

kind regards

-- 
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