Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 509
Ilia Choly Avatar asked Sep 27 '12 18:09

Ilia Choly


1 Answers

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) 
like image 68
noahlz Avatar answered Oct 03 '22 08:10

noahlz