Clojure has a couple of macro-like features built right into the reader, providing shorthand notation for commonly needed constructs. However, unlike real macros, which are built on a sound conceptual framework that guarantees arbitrary composability (macro calls can contain macros and expand into other macros), the different macro-like features in the reader don’t always play well together.
Consider the following piece of code:
(defmacro foo [x] `(map #(identity %) [~x]))
At first sight, nothing looks wrong with this, other than it doesn’t do anything useful. But any use of this macro causes an error message:
(foo [:a :b]) java.lang.Exception: Can't use qualified name as parameter: user/p1__3328
What’s going on here? The error message hints at a problem with a function argument. The only function being defined is here
#(identity %), which uses a shorthand notation for function literals expanded by the reader. Let’s see what the macro call expands to:
(macroexpand-1 '(foo [:a :b]))
(clojure.core/map (fn* [user/p1__3328] (clojure.core/identity user/p1__3328)) [[:a :b]])
So here’s the problem:
#(identity %) is expanded by the reader into
(fn* [p1__3328] (identity p1__3328)). This is a perfectly valid function literal, but the other reader feature used here, syntax-quote, doesn’t know about function literals. It takes the expanded function literal as an arbitrary form and does namespace resolution on all symbols. This leads to a namespace-qualified symbol for a function parameter, which is not legal Clojure syntax.
Moral: use reader features sparingly, ideally one at a time. Except for syntax-quote, they only save you a couple of keystrokes, a convenience that you may end up paying a high price for in terms of debugging time.