` syntax quote

syntaxsince v0.0-1853 in clojureEdit

Expands to a clojure expression (at read time) which—when evaluated—produces the literal structure described by the template inside.

  • `(foo 123) => (cljs.user/foo 123) - symbols become fully-qualified
  • `(foo ~x) => (cljs.user/foo 123) - interpolates the value of x
  • `(foo ~@y) => (cljs.user/foo 1 2 3) - interpolates and splices the sequence of y
  • `(foo bar#) => (cljs.user/foo bar__20418__auto__) - make symbols ending in # unique

Details:

Produces a similar structure to that produced by ' quote, but with important differences:

  • Symbols are auto-resolved to include their namespace, preventing ambiguous symbols at the time of evaluation.
  • Evaluated forms can be inserted using ~ unquote.
  • Any non-namespaced symbols ending with # are replaced with unique symbols. See # auto-gensym.

Though it is often used for code-generation at macro-expansion time, it is very useful at runtime for constructing collections without requiring the usual API ceremony:

(def foo [2 3 4])
(def bar 7)
(def baz `[1 ~@foo 5 6 ~bar])
baz
;;=> [1 2 3 4 5 6 7]

You can peek at the code generated to construct the vector by quoting it:

(def foo [2 3 4])
(def bar 7)
(quote `[1 ~@foo 5 6 ~bar])
;;=> (clojure.core/vec (clojure.core/sequence (clojure.core/seq (clojure.core/concat (clojure.core/list 1) foo (clojure.core/list 5) (clojure.core/list 6) (clojure.core/list bar)))))

;; pretty-print it!
(pp)
;; (clojure.core/vec
;;  (clojure.core/sequence
;;   (clojure.core/seq
;;    (clojure.core/concat
;;     (clojure.core/list 1)
;;     foo
;;     (clojure.core/list 5)
;;     (clojure.core/list 6)
;;     (clojure.core/list bar)))))

Examples:

`foo
;;=> cljs.user/foo

`foo#
;;=> foo__20418__auto__

`(def foo 1)
;;=> (def cljs.user/foo 1)

See Also:


Reader code @ tools.reader:src/main/clojure/clojure/tools/reader.clj
(defn- read-syntax-quote
  [rdr backquote opts pending-forms]
  (binding [gensym-env {}]
    (-> (read* rdr true nil opts pending-forms)
      syntax-quote*)))

Reader table @ tools.reader:src/main/clojure/clojure/tools/reader.clj
(defn- macros [ch]
  (case ch
    \" read-string*
    \: read-keyword
    \; read-comment
    \' (wrapping-reader 'quote)
    \@ (wrapping-reader 'clojure.core/deref)
    \^ read-meta
    \` read-syntax-quote ;;(wrapping-reader 'syntax-quote)
    \~ read-unquote
    \( read-list
    \) read-unmatched-delimiter
    \[ read-vector
    \] read-unmatched-delimiter
    \{ read-map
    \} read-unmatched-delimiter
    \\ read-char*
    \% read-arg
    \# read-dispatch
    nil))