4
votes

Consider

(defn f ^{:foo "bar"} [x] (* x x))

and

(defn g #^{:foo "bar"} [x] (* x x))

Both compile and run.

I have two questions: first, why do (meta f) and (meta g) produce only nil? I would have expected them to produce {:foo "bar"}; i.o.w., am I just completely out to lunch on metadata and have I defined some kind of garbage out there?

Second, what is the difference between the two syntaces for the metadata? It looks like the second one is a "tagged literal," something to do with edn, the extended data notation, but I can't quite noodle it out without some more context or examples.

1

1 Answers

8
votes

The #^ metadata reader macro was replaced with ^ in clojure 1.2. While there is currently no difference between the two, the old form is deprecated and you should be using ^ exclusively.

The metadata literal should come before the item it is to be attached to:

(defn ^{:foo "bar"} f [x] (* x x))

Another thing to keep in mind is that the metadata in the above definition isn't attached to the function, it is attached to the var that refers to the function. You can get the metadata of the f var with:

(meta (var f))

Or using the var reader macro:

(meta #'f)