On May 8, 2014, at 8:34 AM, Pascal Germroth <funkyco...@gmail.com> wrote:
> I'm trying to attach metadata to some values (not the vars holding them). > I thought ^{x} y was the same as (with-meta y {x}), There was a recent thread about this here. https://groups.google.com/forum/#!searchin/clojure/metadata$20reader/clojure/iyYwwWPgv2U/xh-4SonzudkJ ^ is a reader macro that applies metadata to a target. The target is the result of reading the form that immediately follows the metadata form. ^ operates at read time, after the target form is read, but before it is evaluated. There are some subtleties in your example that make exactly what's happening not obvious. As a tool for understanding, read-string on a string can help by giving you visibility into the reader's operation alone. This is in contrast to the REPL where the result you see is after both read and eval have completed. > but while it works for f2/f4, f1's metadata is nowhere to be found, while f3 > works as expected: > > (def f1 "doc" ^{:x 1} (partial inc)) > (meta f1) ; nil, unexpected > (meta #'f1) ; contains :doc, but not :x, as expected The target form in this case is "(partial inc)". Checking (read-string "(partial inc)") confirms that the reader returns a list containing two symbols. The reader macro ^ applied the metadata to that list. The evaluator then evaluated that list by invoking the function bound to the var clojure.core/partial. That function has no access to the metadata on the list that the reader read. After evaluation there is no longer any reference to that list or its metadata. They are both dropped. > (def f2 "doc" ^{:x 2} #(inc %)) > (meta f2) ; {:x 2}, as expected > (meta #'f2) ; contains :doc, but not :x, as expected The target form in this case is "#(inc %)". (read-string "#(inc %)") shows that the reader returns a list like this (containing a symbol, a vector, and a list): (fn* [p1__1925#] (inc p1__1925#)) The name fn* is an implementation detail, you can think of it as fn. Because fn is a special form, it does have access to the list that was returned by the reader and the metadata on it. One thing fn does is transfer the metadata on that list to the function object it creates. That's why (meta f2) works as you expected. There was no metadata applied to the symbol f2. If there had been it would have been transferred by the special form def to the var it created. Your expectation here is probably based on the action of the defn macro which transfers metadata in a defn form to the var it creates. > (def f3 "doc" (with-meta (partial inc) {:x 3})) > (meta f3) ; {:x 3} with-meta operates after (partial inc) is evaluated so it applies the metadata to the function object returned by partial. > (def f4 "doc" (with-meta #(inc %) {:x 4})) > (meta f4) ; {:x 4} same here. --Steve -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.