Sticky SET-WORD! Binding Problem In MAKE OBJECT!

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