Could strings have context?



A common problem faced within Rebol is passing string-based templates to functions without any context attached to them. What would it take/cost to add context to string values? An example:

my-context: make object! [
    x: 10
    template: "x"

reduce load my-context/template

The thought would be a string in source would adopt its parent context, otherwise would be unbound.


The CSCAPE templating function used in generating C code files during bootstrap is a very pertinent example of this problem, e.g. here:

make-inline-proxy: func [
    return: [text!]
    internal [text!]
    cscape/with {
        inline static $<Returns> $<Name>_inline($<Wrapper-Params>) {
            $<opt-return> $<Internal>($<Proxied-Args>);
    } reduce [api 'internal]

Part of why it works in bootstrap without having to supply more context is that the boot process really uses the user context as the place where most stuff is put. It’s somewhat ad-hoc. If it were broken down better with more locals, then CSCAPE wouldn’t know where to look.

One thing Ren-C can do that historical Rebol and Red can’t is to be able to locate function parameters and locals from the binding of any argument or local (or the literal FRAME! value itself). It’s not a solution, but it’s better than in R3-Alpha where if you asked for the binding of a function local or arg you just got “true”, and there was no ANY-CONTEXT! to find your locals from.

No real solutions off the top of my head, just agreeing that this is something that needs to be thought more about.


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.