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
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.