syntax | since v0.0-1853 | in clojure | in edn | Edit |
As a general pattern, syntax forms prefixed with #
are related to their
standalone forms:
relation | original | with # prefix |
---|---|---|
string-related | "" string |
#"" regex |
code-related | () list |
#() function |
lookup-related | {} map |
#{} set |
quote-related | ' quote |
#' var |
ignore-related | _ unused |
#_ ignore |
name-related | foo (symbol) |
#foo (tagged literal) |
conditional-related | ? predicate |
#? reader conditional |
The "symbolic values" ##Inf
, ##-Inf
, ##NaN
do
not follow this pattern, but the additional number sign in ##
serves as a
mnemonic for these special numerical values.
#
is a prefix character that is called the dispatch macro, because it allows
the behavior of the reader to be dispatched to another table, indexed by the
character following the #
.
The dispatch macro is not usable on its own. Rather, it dispatches to other syntax forms.
Regular expression:
#"[a-zA-Z0-9]+"
;;=> #"[a-zA-Z0-9]+"
Set:
#{:foo 1 2}
;;=> #{:foo 1 2}
Function:
#(foo 1 2)
;;=> #;; return cljs.user.foo.call(null,(1),(2));
;; }>
Var reference:
(def a)
#'a
;;=> #'cljs.user/a
Ignore form:
#_foo
;; waits for next form since #_foo was ignored
#_123 456
;;=> 456
Tagged Literals:
#queue [1 2 3]
;;=> #queue [1 2 3]
#js {:foo 1}
;;=> #js {:foo 1}
#inst "2010-11-12T18:14:15.666-00:00"
;;=> #inst "2010-11-12T18:14:15.666-00:00"
Reader Conditional:
#?(:clj "Clojure" :cljs "ClojureScript")
;;=> "ClojureScript"
(defn- read-dispatch
[rdr _ opts pending-forms]
(if-let [ch (read-char rdr)]
(if-let [dm (dispatch-macros ch)]
(dm rdr ch opts pending-forms)
(read-tagged (doto rdr (unread ch)) ch opts pending-forms)) ;; ctor reader is implemented as a tagged literal
(err/throw-eof-at-dispatch rdr)))
(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))