Search code examples
syntaxclojure

Does a Clojure symbol starting with & have special meaning?


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.


Solution

  • 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.