syntax | since v0.0-1853 | in clojure | Edit |
Shorthand for specifying namespaced keywords. Allows you to use an aliased namespace or to have the current one auto-inserted if not specified.
::foo/bar
=> :aliased-ns/bar
::bar
=> :current-ns/bar
Keywords starting with ::
will evaluate to regular keywords with a namespace qualification.
The namespace will resolve to either of the following:
If we are in the user
namespace:
::foo
;;=> :user/foo
We can use namespace aliases:
(require '[example.util :as util])
::util/foo
;;=> :example.util/foo
Existing namespaces will resolve normally:
::cljs.core/foo
;;=> :cljs.core/foo
Non-existing namespaces will throw a reader exception:
::foo/bar
;; clojure.lang.ExceptionInfo: Invalid token: ::foo/bar {:type :reader-exception, ...
(defn- read-keyword
[reader initch opts pending-forms]
(let [ch (read-char reader)]
(if-not (whitespace? ch)
(let [token (read-token reader :keyword ch)
s (parse-symbol token)]
(if s
(let [^String ns (s 0)
^String name (s 1)]
(if (identical? \: (nth token 0))
(if ns
(let [ns (resolve-alias (symbol (subs ns 1)))]
(if ns
(keyword (str ns) name)
(err/throw-invalid reader :keyword (str \: token))))
(keyword (str *ns*) (subs name 1)))
(keyword ns name)))
(err/throw-invalid reader :keyword (str \: token))))
(err/throw-single-colon reader))))
(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))