convex
convex copied to clipboard
Redefining looses metadata
It is not a bug per se, rather behavior that may seem unexpected.
(def foo ^{:a :b} 42)
(lookup-meta 'foo) ;; {:a :b}
(def foo 24)
(lookup-meta 'foo) ;; nil
One might say this is perfectly expected. However, conceptually, metadata is attached to a symbol, not to the value it points to. So personally I find it counter-intuitive that binding a new value throws current metadata away. I find myself having to create a special function which redefines a value with the same metadata.
What do you think? I would say it is legit overwriting metadata when requested, but not to do anything else otherwise.
In two minds about this. Keeping old metadata by default might be dangerous (e.g. tags like :expander or security sensitive stuff)
Perhaps we want something like set! to work with defined values without changing metadata?
I changed behaviour a bit, redefining now doesn't change metadata (unless you set new metadata explicitly)
I thought it was a regression at first but probably not: while this has been fixed for def, defn still has the old behavior of removing metadata when none are supplied in the redefinition.
It is less noticeable because "values" are redefined way more often than functions but behavior should be consistent.
This is probably because defn itself does some macro magic which probably affects metadata. Will need to re-check.