convex icon indicating copy to clipboard operation
convex copied to clipboard

Redefining looses metadata

Open helins opened this issue 4 years ago • 4 comments

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.

helins avatar Jul 16 '21 14:07 helins

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?

mikera avatar Jul 17 '21 02:07 mikera

I changed behaviour a bit, redefining now doesn't change metadata (unless you set new metadata explicitly)

mikera avatar Jul 17 '21 03:07 mikera

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.

helins avatar Aug 29 '22 07:08 helins

This is probably because defn itself does some macro magic which probably affects metadata. Will need to re-check.

mikera avatar Aug 30 '22 16:08 mikera