metadata question

106 views
Skip to first unread message

wubbie

unread,
Jan 6, 2009, 11:35:57 PM1/6/09
to Clojure

Hi,
Here is the question on differences between with-meta and #^
Specifically 1) and 2) are different in that 1) has meta info carried
over
to jumping-wubbie, while 2) has not.
What's the rationale behind this?


user=> (def wubbie {:name "Wubbie" :email "wub...@gmail.com"})
#'user/wubbie
user=> wubbie
{:name "Wubbie", :email "wub...@gmail.com"}
user=> ^wubbie
nil
user=> (def jumping-wubbie (with-meta wubbie {:jumping true})) ;; 1)
meta info set
#'user/jumping-wubbie
user=> ^jumping-wubbie
{:jumping true}
user=> (def jumping-wubbie2 #^{:jumping true} wubbie) ;; 2) meta inof
not carried over
#'user/jumping-wubbie2
user=> ^jumping-wubbie2
nil


Thanks
Sun

RZez...@gmail.com

unread,
Jan 7, 2009, 12:44:41 AM1/7/09
to Clojure
Stu H. mentions this in his book.

The briefest way to explain it is with the following code:

user=> (= #^{:jumping true} {:name "Wubbie", :email
"wub...@mgail.com"} #^{:jumping true} wubbie)
false

In the case of "#^{metadata} symbol" you are adding the metadata to
the symbol, but then the symbol gets evaluated and it's *value* is
returned, not the metadata.

Maybe this makes it more clear?

user=> (meta #^{:jumping true} wubbie)
nil

I'm very much a Clojure n00b, but I would also expect the behavior you
were expecting. I wonder if this implementation of #^ was intended,
or if this was just an oversight? I think there is something lacking
in my fundamental knowledge of Clojure, and that's why this has yet to
make complete sense to me.

RZez...@gmail.com

unread,
Jan 7, 2009, 1:01:33 AM1/7/09
to Clojure
Looking at how the #^ macro is used in core.clj confuses me even more.

For example:

user=> (def #^{:arglist '([name]) :doc "Say hello."} hello (fn hello
[name] (println (str "Hello, " name))))
#'user/hello
user=> (hello "ryan")
Hello, ryan
nil

I mean I kind of follow it, but not totally. Is this macro explained
somewhere?

-Ryan

Christophe Grand

unread,
Jan 7, 2009, 3:25:49 AM1/7/09
to clo...@googlegroups.com
rzez...@gmail.com a écrit :
#^{:arglist '([name]) :doc "Say hello."} hello indeed adds the metadata
to the symbol but def copies the symbol metadata to make the var metadata.
http://code.google.com/p/clojure/source/browse/trunk/src/jvm/clojure/lang/Compiler.java#363

Christophe

Rich Hickey

unread,
Jan 7, 2009, 10:37:09 AM1/7/09
to Clojure

RZez...@gmail.com

unread,
Jan 7, 2009, 11:46:19 AM1/7/09
to Clojure
Perfect! Thanks Rich. I actually read over this thread before but
completely forgot about it (this group has really picked up steam over
the last couple of months). Next time I'll try searching the group
more, rather than adding more noise.

However, I will reiterate the last threads conclusion. #^ is not a
macro for with-meta. That is what I think tripped me up. I may still
not understand the full power of #^, but as long as I remember it's
not sugar for with-meta than I should at least avoid shooting myself
in the foot.

-Ryan
Reply all
Reply to author
Forward
0 new messages