In making the change to where "strict mode is always enforced", a problem was noticed with FOR-PARALLEL:
The caller is passing in a VARS block like [x y]
. And what was happening here was that due to attachment binding, X and Y were just being pushed out as declarations into whatever the binding of that block was.
That is not what was intended. What was intended was that X and Y be new definitions for the body of the loop. (Good catch, strict mode! )
Now the tricky part: what to do about it. The block you get was already bound at the callsite (wasn't quoted)... though despite that, plain words inside of it represent instructions to make new bindings for the body. So we need to override those bindings if we're going to use it as a SET-BLOCK! to do the assignments.
Hence vars
needs to be "overbound" with new definitions.
A crude attempt might leverage the mechanics of "decide what to do about SET-BLOCK!" already built into WRAP:
blk: inside vars compose [(unbind vars):] ; extract binding to tip
blk: wrap blk ; e.g. gen bindings for [[x y]:]
vars: inside blk blk.1 ; put binding onto unbound block [x y]:
This lets WRAP take care of the "overbinding" because we moved the full binding of the vars block to the tip, and that's what WRAP does.
But better would be if WRAP just offered this as a fundamental operation. It could be the behavior applied when you pass it a SET-BLOCK!, but I don't like cueing behavior on type like that for such primitives.
So it could be wrap:set-block
, or as you're passing a block just wrap:set
to mean "wrap with set-block semantics".
vars: wrap:set vars
But wait, what about the body? 
The body needs to be bound to the context created for the variables. And the variables need to be created only once if they're calculated from GROUP!s!
Okay, this is starting to get complicated. We need to COMPOSE the block to make sure any GROUP!s are evaluated once--not each time per loop iteration. And we need an operation that gives us back the context, and binds the variable block.
It seems WRAP needs a secondary multi-return, to give us back the context it made so we can use it on the body block.
[vars context]: wrap:set compose vars
body: overbind context body
Note that it would be "sketchy" if we tried to extract the context from the block result of WRAP. That block is bound not just to the context made for the variables, but other things (like the context to know how to evaluate embedded groups). We aren't interested in carrying over the full binding on vars
from the callsite that had [x (some-func [blah y])]
because SOME-FUNC and BLAH may be visible in the vars block but should not be made visible to the body.
Crazy stuff...but, this is what you have to do if you want things to actually work.