Ilia Choly
Ilia Choly

Reputation: 18557

with-meta vs ^{} - Clojure

I'm confused as to the differences between using with-meta and the ^ reader macro.

Attach metadata too baz symbol using the reader macro

user=> (def ^{:foo "bar"} baz {:my "value"})
#'user/baz

pull it out

user=> (meta #'baz)
{:foo "bar", :ns #<Namespace user>, :name baz, :line 1, :file "NO_SOURCE_PATH"}

attach using with-meta

user=> (def (with-meta 'baz2 {:foo "bar"}) {:my "value"})
CompilerException java.lang.RuntimeException: First argument to def must be a Symbol, compiling:(NO_SOURCE_PATH:1) 

however ...

user=> (class (with-meta 'baz2 {:foo "bar"}))
clojure.lang.Symbol

I can attach it to the value

user=> (def baz2 (with-meta {:my "value"} {:foo "bar"})
#'user/baz2

but it's not the same

user=> (meta baz2)
{:foo "bar"}

user=> (meta #'baz2)
{:ns #<Namespace user>, :name baz2, :line 1, :file "NO_SOURCE_PATH"}

can someone explain this?

Upvotes: 7

Views: 501

Answers (1)

noahlz
noahlz

Reputation: 10311

def is a special form. Even though with-meta returns a symbol, the Clojure compiler doesn't (can't) know that. It sees a function.

user=> (def (symbol blah) "blah")
CompilerException java.lang.RuntimeException: First argument to def must be a Symbol, compiling:(NO_SOURCE_PATH:1) 

Upvotes: 5

Related Questions