# dispatch

syntaxsince v0.0-1853 in clojure in ednEdit

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.


Details:

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


Examples:

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)
;;=> #<function (){
;;   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"

See Also:


Reader code @ tools.reader:src/main/clojure/clojure/tools/reader.clj
(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 taggedx literal
    (err/throw-eof-at-dispatch rdr)))

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))