This raises the question of how often constructs should UNBIND material they get vs. error.
The case in question was with UPARSE's EMIT.
>> label1: 'name
>> parse [foo 1 2 3 bar 4 5] [collect [
some keep gather [
emit (label1): word!, emit list: collect some keep integer!]
]
]]
== [
make object! [
name: 'foo
list: [1 2 3]
]
make object! [
name: 'bar
list: [4 5]
]
(Note: I think this motivates ACCUMULATE INTEGER! as a synonym for COLLECT SOME KEEP INTEGER! and ACCUMULATE GATHER as a synonym for COLLECT SOME KEEP GATHER)
What EMIT does is adds a SET-WORD! and a META of the value it gets to a block:
[name: 'foo list: '[1 2 3]]
Then it runs MAKE OBJECT! on the result.
What was happening was that the incoming WORD! here (name) was bound. So the SET-WORD! in that block was bound.
-
If EMIT doesn't report the error it goes into the MAKE OBJECT! and will error. Error locality is better if it reports an error.
-
It could also just remove the binding and keep going.
- Yet removing the binding may gloss over potential misunderstandings you had by passing something with a binding in.
Implication For Casual Creation of Bound Items
I'm observing you need to be wary of the style:
for-each item block [
item: in block item
...
]
Because if you do any insertions of that item into code, they will be bound. You probably should wait to do the IN until you need to do a lookup, and work with unbound items as long as possible...