Why is it stated that metadata is a property of symbols?

…when it is contradicted by meta function usage:

(def ^:metadata X 0)    
(meta 'X) => nil
(meta #'X) =>  {:metadata true, ...

Both clojure.lang.Var, and clojure.lang.Symbol support IMeta interface, but apparently def-ing attaches metadata to the former.

Metadata is a map associated with some kinds of objects: Symbols, Lists, Vector, Sets, Maps, tagged literals returning an IMeta, and record, type, and constructor calls. - from clojure.org

Am I missing some technical, or philosophical detail here?

def is a special form and its syntax allows to add metadata on the var your are creating. It does not attach that metadata also to the value. Typical metadata fields attached to a var are :docstring, :private and/or :macro. If you want to add metadata to the value that the var is pointing to, e.g. a symbol, you can do that with with-meta, vary-meta, etc.:

(-> 'foo (with-meta {:a 1}) meta)
{:a 1}

I use that feature a lot in clj-kondo. Not all values can carry metadata, for examples strings and keywords cannot.

Yes, I see, as I mentioned clojure.land.Symbol supports IMeta, so surely a symbol can carry metadata. My question is more about why clojure.org insists on symbol-metadata relationship omitting that of var-metadata in spite of the fact it is clearly present in idiomatic usage (def). I’m trying to find a hidden meaning in the wording, though I’m not sure it exists :slight_smile:

I’m not sure, but reasons the metadata is not duplicated onto the value as well, could be:

  • not really needed in practice, having it in one predicable place is sufficient
  • duplication leads to data going out of sync
  • not all values can take metadata

This is just me guessing :).

The missing bit in the clojure.org docs is probably just an oversight.

Re vars - def is a special form to make vars, and it thus makes sense for the meta you supply to be attached to vars (as that’s what def makes). The symbol here is just used as a key internally in namespace state, it doesn’t really make sense to attach the metadata to the symbol. Other symbol makers may want different metadata when they make their symbol. And the value referred to by the var is independent and may have different metadata - you can attach it there as well (when it’s appropriate).

In summary, the var, symbol, and value are all different entities with different uses and constraints.

2 Likes

Now I see I completely misunderstood the issue and interpreted it as the metadata going on the the value that is contained in the var… LOL, sorry.

No prob, happens to the best of us :slight_smile:

Thanks, Alex! Makes sense. I probably overthought this stuff.