:: keyword

syntaxsince v0.0-1853 in clojureEdit

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:

  • current namespace if none is specified
  • given namespace if it exists
  • full namespace if the given one is an alias
  • reader error if given namespace doesn't exist


If we are in the user namespace:

;;=> :user/foo

We can use namespace aliases:

(require '[example.util :as util])

;;=> :example.util/foo

Existing namespaces will resolve normally:

;;=> :cljs.core/foo

Non-existing namespaces will throw a reader exception:

;; clojure.lang.ExceptionInfo: Invalid token: ::foo/bar {:type :reader-exception, ...

See Also:

Reader code @ tools.reader:src/main/clojure/clojure/tools/reader.clj
(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))))

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