Let’s say that I want to define a macro called defsomething
such that this:
(defspecial a x)
…expands into this:
(def a (f `a x))
That syntax-quotation `a
there is the tricky part. I don’t see how I can attach the current namespace to the symbol properly so that it behaves like the syntax-quote. For instance:
(defmacro defspecial [var-symbol expr]
`(def ~var-symbol (f '~var-symbol ~expr)))
(defspecial a x)
…expands into:
(def a (f 'a x))
…which is close, but that second a
is not namespace-qualified.
I know I could use *ns*
:
(defmacro defspecial [var-symbol expr]
`(def ~var-symbol (f (symbol (name (ns-name *ns*)) (name '~var-symbol)) ~expr)))
…but I don’t like that; not only is it ugly, *ns*
is rebindable, so this would be possible:
(binding [*ns* (the-ns 'clojure.core)]
(defspecial a 5))
Unfortunately, Clojure apparently has no syntax-quote
form for `
like it has quote
for '
. And so, how should I best implement this macro, then?
Have you actually tried the last example you gave? The compiler's binding of *ns*
happens at compile-time, as does the macroexpansion, so the run-time binding you do should have no effect on the behavior of defspecial
.