I was browsing core.clj in Clojure's source code and came across the definition of defn
. The function it defines takes several arguments, the first of which are &form
and &env
:
(def
defn (fn defn [&form &env name & fdecl]
;; ...
))
Do these names take on special meaning because they start with &
?
I know about rest args and the shorthand anonymous function var %&
, but this doesn't seem to be either of those things.
I wasn't able to find anything about this syntax in the Reader reference, which doesn't mention &
explicitly:
Symbols begin with a non-numeric character and can contain alphanumeric characters and *, +, !, -, _, ', ?, <, > and = (other characters may be allowed eventually).
Reading Clojure Characters also doesn't appear to mention this. resolve
includes an &env
arg in its doc string but doesn't elaborate.
The symbols &form
and &env
represent special variables used in Clojure macros: https://clojure.org/reference/macros#_special_variables.
In particular, you may use the &form
variable to access the line number at which the macro is being evaluated
(:line (meta &form))
which is useful in printing error messages, etc.
Side note on searching for symbol-heavy terms:
SymbolHound.com is a search engine that does not elide symbols like Google, so you can often find results there that you can't other places. Searching for clojure &form
yields results.
Update
Looking at the source code we see that in the Clojure bootstrapping process, fn
is a macro making use of fn*
:
(def
^{:macro true
:added "1.0"}
fn (fn* fn [&form &env & decl]
(.withMeta ^clojure.lang.IObj (cons 'fn* decl)
(.meta ^clojure.lang.IMeta &form))))
So that is how the compiler injects &form
, etc.