Trying to use the policy that bindings don't override, I ran into a bug with MAKE OBJECT! when a SET-WORD! is carrying a pre-existing binding.
What happens is that a new field is made (cued by seeing a top-level SET-WORD!) but then when the body is executed it uses the old binding... so the newly created field remains unassigned, and the old value is updated.
>> obj: make object! [x: 10]
== make object! [
x: 10
]
>> block: compose [(bind 'x: obj) <new>]
== [x: <new>]
>> obj2: make object! block
== make object! [
x: ~
]
>> obj
== make object! [
x: <new>
]
This hints at a class of hard-to-reason-about cases. The more you use material with hardened bindings, the more you'll see them come up.
(I hit the problem in the whitespace dialect code, which is still using mutable binding when it probably should not... but, it gives a good example of a problem that happens if you do... and if we're living in the non-binding-overriding world.)
For the moment, I think I'm going to say that MAKE OBJECT! will error if any of the SET-WORD!s in the top level already have a binding.
-
Binding can't serve two masters. If the code were more complex than the above, it's not clear to say that the original binding didn't mean what it said in terms of intending a specific assignment... vs wanting to be overridden.
-
I don't want fundamentals like this to use mutable binding, and to get this to work virtually at one-level of depth would require a tricky bind instruction that I don't want to deal with right now.
I'd say it's the first "major" problem I've seen in practice from a policy of not overriding binding (in the sense that it's fairly hard to argue "well, maybe you wanted that").