Hello, welcome! Feel free to post an introduction if you like.
Rebol has a GET function which has historically operated as single-arity. You pass it a WORD!, and "bound words" have context attached which allow them to be looked up: get word
If you have an unbound word, then you could use the arity-2 operation IN to manufacture a word with context. So (get (in context word)) or simply get in context word.
If blocks are able to carry some form of scoping information, it doesn't seem all that useful to prohibit words from carrying this information as a convenience. (It would also break all existing code to make GET arity-2...which I'm not afraid to do if it improves things, but I don't see how disabling words from holding scope would be an improvement.)
So in the model of blocks being "in control" of imbuing words with scope, you'd simply have words carrying the scope of wherever they are last picked out of. Then poking an isolated word into a block would lose the scope it was carrying, and it would assume the context of the new location.
But there are limitations to having blocks (and groups) retain their scopes with words deferring to whatever blocks (or groups) they're put under. One choice would be that you could say that unbound words would act this way... making it a pretty easy behavior to get e.g. append block unbind word. Then the default behavior would be to preserve whatever binding was traveling with the word.
This is something I cover in Rebol and Scopes: Well, Why Not? (which is worth reading if you haven't already). I have experimented with mechanisms that build chains of scope, which are indeed carried by the blocks:
"FUNC stows the body block away in an ACTION! that it generates. Later when it gets invoked, it creates a FRAME! with
return
andx
in it...and puts that in a chain with the module context. So upon entry to the function body, that body is being executed with a specifier that looks in the frame first (would find that x) and then in the module second (would findglobal
andfoo
). This compound specifier is what the evaluator state initially has for that body block."
I should point out that it's block values that carry these virtualized scopes, not block series. So each function invocation--even though it's using the same arrays of items in memory--gets its own "view" on that data. Making a BLOCK! value as seen by the user a (data, index, scope)
tuple under the hood.
In any case, it would be good to detail any proposal for giving blocks scope as how it contrasts to what I lay out in that post...
That's interesting to know. If you're familiar with R, then posting notable examples of its mechanisms in the Foreign Inspiration category would be quite helpful...I'd be interested to see.