I am trying to use Stuart Sierra's do-template macro inside a defprotocol and the Clojure compiler complains that I am redefining do-template -- not what I intend:
(defprotocol AProtocol
(a-method [_])
(do-template [name]
`(~(symbol (str name "-method")) [this that])
foo
bar
baz))
This should expand to:
(defprotocol AProtocol
(a-method [_])
(foo-method [this that])
(bar-method [this that])
(baz-method [this that]))
The problem (I believe) is that the do-template s-expression is getting passed to defprotocol unexpanded. Is there any way to cause it to evaluate before being passed?
BTW, do-template should actually expand to
(do
(foo-method [this that])
(bar-method [this that])
(baz-method [this that]))
but I already tried that (with a hand-expanded version) and defprotocol is fine with the nested do.
How can I see the actual expansion of the do-template? I tried both (macroexpand '(do-template ...)) and (macroexpand-1 '(do-template ...)) and got:
(do (clojure.core/seq (clojure.core/concat (clojure.core/list (symbol (str foo "-method"))) (clojure.core/list (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/this)) (clojure.core/list (quote user/that)))))))) (clojure.core/seq (clojure.core/concat (clojure.core/list (symbol (str bar "-method"))) (clojure.core/list (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/this)) (clojure.core/list (quote user/that)))))))) (clojure.core/seq (clojure.core/concat (clojure.core/list (symbol (str baz "-method"))) (clojure.core/list (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/this)) (clojure.core/list (quote user/that)))))))))
Not exactly easy to read :-).
Also, I probably want the this and that to be anaphora and expand to themselves: ~'this.