Caching Binding Lookup, and "Attachment Binding"

The problem is that a variable may not exist at all to bind to, and there's never a moment of explicit creation. Yet it's expected to work.

Historical Rebol expected all source words to be bound to something--even it's an unset something. This is because variables were created in advance for all words mentioned in source.

 rebol2>> foo: func [] [set 'whatever 10]  ; whatever bound to user context

 rebol2>> foo
 == 10

 rebol2>> whatever
 == 10

To preserve this behavior without requiring an a-priori walk that creates a ton of spurious variables, I came up with the idea of "attachment". Variables could be attached to a module but not exist in that module... yet. If a SET came along to that attached word, the variable would be created at that moment.

Now that we have to be more explicit about binding, there's still the problem of when that variable would be created:

>> foo: func [] [set in [] 'whatever 10]

>> foo
; ... if we wanted whatever in user context to be 10, how to do that?

SET only receives a WORD!...not the argument to IN. For this to work, either IN had to create the variable (not knowing in advance whether it was going to be SET or not) or it had to bind the word in a state to say "if you get a SET request, here's where you should put the variable."

I've already said that having modules work this "non-strict" way is questionable (it's also a bit of a puzzle to guess what kinds of non-strict module presence in the "environment" should permit emergence, and how that implies a single location--let's imagine there's a methodology to it). But it gives rise to console behaviors that people have come to expect, historical code uses the style, and rightly or wrongly some current code depends on it.

Urgh. Considering attachment binding to be "bound" is kind of unworkable. Because it makes basically the entire body of a non-strict module bound. And we've seen for instance that really basic things will choke on the binding (e.g. MAKE OBJECT! when SET-WORD! is thought to be already bound)

Blindly treating it as unbound isn't good, because as I said, it may have come into existence. So an attached word has to be checked for if it has come into existence before you treat it as unbound.

So if you can't treat it as unconditionally bound or unbound, this means its state can change out from under you.

It's definitely frustrating... I'd like to be able to say "this isn't important, don't support it". But that would be very consequential. Explicit creation of all variables e.g. in the console, we could say it could happen for all top-level definitions e.g. how MAKE OBJECT! works, and wind up with something like this:

>> x: 10 print [x]
10 ; works

>> (y: 10 print [y])
** Error: y is unbound  ; wouldn't work