Not sure what version of Clojure or editor you're using but Clojure 1.10.3 gives more useful output in the standard repl:
user=> (macroexpand '(m))
Syntax error macroexpanding clojure.core/fn at (REPL:1:1).
(user/x) - failed: Extra input at: [:fn-tail :arity-1 :params] spec: :clojure.core.specs.alpha/param-list
user/x - failed: vector? at: [:fn-tail :arity-n :params] spec: :clojure.core.specs.alpha/param-list
As you can see it is not running your code but (recursively) macroexpanding when the problem is encountered. The first expansion will become:
(clojure.core/fn [user/x])
clojure.core/fn
is itself a macro that is expanded. During that expansion, the fn
macro is checked against the fn
spec (this is on by default for macros). The spec finds user/x
and sees it as "extra input" in the :params
because it does not conform to any expected parameter form (unqualified symbols usually, but also all recursive destructuring forms). Really, the problem here is user/x
instead of x
.
You can fix this with:
(defmacro m []
`(fn [~'x]))