In Rebol’s current model, the only viable way to do this is to pair up the bindings you want with the string, something like:
template: [(x y z) "$x and $y and $z"]
Definitional binding moves in a wave, and you only get the chance to make that binding at that moment in time…after which the entity describing the binding environment no longer exists.
Some alternative model might allow the string to capture a pointer to an abstract entity which represents the memory of that binding environment–so you could ask it to look up x and y and z based on that pointer.
This is similar in a way to the aspirations of virtual binding. But virtual binding is intended to act as a light surrogate for adding only a few bindings to code (and maybe flattening them out into a copy if the lookups seem to be happening too often to virtualize). It seems on the surface that trying to recreate the entire binding environment of a string in a reified object could be prohibitive.
But who knows, there may be magic along the lines of persistent vector which could cull the total number of binding environments to something manageable. These things are big unknowable research problems in their own right. It’s hard to say what can be done if it hasn’t been invented!
I think it’s important to keep an open mind and consider the idea that much of the current binding mechanics might have to be thrown out. I’d even be willing to consider linking to another engine (Haskell, Clojure, Graphd, etc.) and delegating the task of binding and management to something within their methodology–for prototyping purposes. Then once we see what might be done abstractly, we could think about how a from-scratch low-level C solution might match it.
The trick is to come up with new superpowers without breaking old behaviors that were are important. What we get from today’s Rebol is a minimum baseline of expectation of the system’s abilities.