Different Environment Lookup for WORD! vs. SET-WORD!

In thinking about whether or not there's something intrinsically necessary about a per-block (or per-group) differentiation of word-binding, I thought of a case where I'd used this.

In SPECIALIZE, it only binds the SET-WORD!s to the frame you are specializing. Regular words (and anything else, refinements, etc.) are left bound as they were:

>> value: [d e]

>> apde: specialize :append [
       value: value  ; SET-WORD! is bound to specialization's frame
   ]

>> apde [a b c]
== [a b c [d e]]

This saves you from the COMPOSE step you'd need otherwise, which is what you have to do with objects:

>> value: [d e]

>> obj: make object! [value: value]
** Script Error: value is ~ isotope

>> obj: make object! compose [value: (value)]
== make object! [
    value: [d e]
]

I'm not sure it's a critical feature to preserve. If it turned out some alternative conception of binding wouldn't permit the inconsistency... and that conception offered some great advantage... I'd be willing to lose it. There are legitimate arguments against doing such trickery behind people's backs, maybe the COMPOSE helps you keep it straight:

>> value: [d e]

>> ap5: specialize :append [
       value: 5
       assert [value = 5]  ; assertion failure, but I just set it!
   ]

But I wanted to catalog it as a case of "arbitrary binding logic" that's in place at present.

The way this feature is accomplished today isn't by deep-walking the block and binding SET-WORD!s and WORD!s differently. It's with a specifier "instruction" that is put in the chain that says "propagate a binding, but only for SET-WORD!s". It propagates down through the evaluator as each block is extracted.

There's no user exposure of that feature... it's something that only SPECIALIZE (and the esoteric APPLIQUE) can do at the moment.

@bradrn has stated aspirations to make environments/specifiers "first class values", so instructions like this for hole-punching, or narrowing the categories of words...would make those values weirder.

I've thought to conceptualize "coalesced binding" (now manifest as IN) as basically just a function: I give you something that may or may not be bound already with some shape of that binding, you give me a newly shaped thing. This newly shaped thing is a "binding machine" that needs to know how to do two things:

  1. coalesce with another environment

  2. turn a value into something that can be looked up with GET and assigned with SET, or leave it alone

We'll be discussing this more... but it's within the realm of possibility to say that the ultimate desired implementation will be able to target discerned binding in the vein of this "SET-WORD!-only" rule.

Regardless, the mechanism from today should keep working when I take a second shot at "pure virtual binding" using the new perspectives @bradrn and I have been hammering out. (The trick will be rewriting all the usermode dialects to use IN everywhere...correctly.)

But Just Because We Can Do This, Should SPECIALIZE Do It?

I wanted to break this out into a separate topic to specifically discuss the question of if this is a good idea or not.

I've pointed out something that doesn't have such a good look:

>> value: [d e]

>> ap5: specialize :append [
       value: 5
       assert [value = 5]  ; assertion failure, but I just set it!
   ]

We're embracing the idea that in a pinch, you can go to the level of binding things explicitly wherever you want to, but should basic constructs avoid being this weird?

There are places in other languages where kind of parallel things are seen as advantageous:

 struct Foo {
     int x;
     Foo (int x) : x {x} {
         // x {x} initializes member x with constructor's argument
     }
 };

I'm kind of ambivalent about it in SPECIALIZE. It's sneaky. But when I think about striking it, I think about how annoying the need for a COMPOSE is.

One thing you’ve glossed over… at least in my presentation, individual words can still receive bindings! (Even though they’re unbound by default.) So it’s still possible to traverse over the BLOCK binding all the SET-WORD!s as you go. It would require a traverse, but it’s possible if this is really something worth preserving.

1 Like

2 posts were merged into an existing topic: What Dialects Need From Binding