^ meta

syntaxsince v0.0-1853 in clojureEdit

Attach metadata to the following symbol or collection. Use a map to specify the metadata, or use shorthand:

  • ^:foo => ^{:foo true}
  • ^"foo" => ^{:tag "foo"}
  • ^foo => ^{:tag foo}

Examples:

Attach metadata to a collection:

^:foo [1 2 3]
;;=> [1 2 3]

View the resulting metadata:

(meta ^:foo [1 2 3])
;;=> {:foo true}

(meta ^{:foo "bar"} [1 2 3])
;;=> {:foo "bar"}

(meta ^"foo" [1 2 3])
;;=> {:tag "foo"}

(def foo 1)
(meta ^foo [1 2 3])
;;=> {:tag 1}

Chain metadata:

(meta ^:foo ^"foo" [1 2 3])
;;=> {:foo true, :tag "foo"}

Generally, metadata maps used purely by the compiler are not evaluated and should be read literally:

(defn foo [^js x]   ;; ^js => ^{:tag js}   (literal map not evaluated)
  ^js (.-bar x))    ;; ^js => ^{:tag js}   (literal map not evaluated)

But here’s one exception— metadata maps are evaluated when placed behind literal collections created at runtime:

(def foo (+ 1 2 3))
(meta ^foo {})                ;;=> {:tag 6}   not {:tag foo}
(meta ^{:foo (+ 1 2 3)} [])   ;;=> {:foo 6}   not {:foo (+ 1 2 3)}

See Also:


Reader code @ tools.reader:src/main/clojure/clojure/tools/reader.clj
(defn- read-meta
  [rdr _ opts pending-forms]
  (log-source rdr
    (let [[line column] (starting-line-col-info rdr)
          m (desugar-meta (read* rdr true nil opts pending-forms))]
      (when-not (map? m)
        (err/throw-bad-metadata rdr m))
      (let [o (read* rdr true nil opts pending-forms)]
        (if (instance? IMeta o)
          (let [m (if (and line (seq? o))
                    (assoc m :line line :column column)
                    m)]
            (if (instance? IObj o)
              (with-meta o (merge (meta o) m))
              (reset-meta! o m)))
          (err/throw-bad-metadata-target rdr o))))))

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