The Evaluator's TUPLE! Dialect

I've spoken about the rich possibilites offered to us with CHAIN!, to be able to dialect function calls:

https://rebol.metaeducation.com/t/dialecting-function-calls-new-weird-powerful/2310

We have another opportunity to do something cool with TUPLE!.

On the surface, we might think that TUPLE! has to be literal, e.g.

>> m: make map! @[^foo 10 ''bar 20 [baz] 30]

>> m.^foo
== 10

>> m.''bar
== 20

>> m.[baz]
== 30

But this would restrict us to a meaning for quotes, sigils, blocks, fences, etc. that wouldn't have meanings lots of places. The only TUPLE! accesses you could have that would be meaningful for OBJECT!s would be WORD! (for instance).

We Know What GROUP! Does...

We already have the premise that a GROUP! will evaluate, which covers all the above for MAP! if you want it:

>> m.('^foo)
== 10

>> m.(the ''bar)
== 20

>> m.([baz])
== 30

I Think QUOTED! Should UNBIND

We now have a default that binding is applied on picking:

>> x: 1020

>> code: [x]

>> code.1
== x  ; bound

>> get code.1
== 1020

You don't always want this. If you're picking through some kind of specification block, and it names things that are going to be named in a function you generate, and then you put a reference to that thing in the function body, you want it to be unbound so it picks up the instance from the function.

>> unbind code.1
== x  ; unbound

I think it's common enough that a shorthand is warranted (and it lines up with the shorthand elsewhere):

>> code.'1
== x  ; unbound

This would apply to GROUP! as well, allowing it to calculate:

>> code.'(3 - 2)
== x  ; unbound

And it would compose with any other dialected part we pick.

It's a little too bad that it "wastes" the meaning of more than one quote, but I don't think it matters.

How About BLOCK!s?

Since we've ruled out using quotes, blocks could be literal lookups. :thinking:

>> m: make map! [^x 10 ^y 20]

>> map.[^x]
== 10

Or, there were proposals once upon a time that it might be used for 0-based lookup.

>> block: [a b c]

>> block.(1 + 1)  ; one-based 2 pick
== b

>> block.[1 + 1]  ; zero-based 2 pick
== c

Presumably @foo is iterator dereference

But it seems that due to the way things work, @foo.bar would act like foo.@bar, because the @ decoration is "on top of" the tuple.

So this would be for things like obj1.@obj2.iter or obj1.@(iter).field

Maybe $var Is Synonym for (var)?

>> num: 1

>> block: [a b c]

>> block.(num)
== a

>> block.$num 
== a

If we went this direction, it makes it seem like $ should be what the parse dialect uses for "I mean what's in the variable".

It's a bit annoyingly inconsistent with what $num means standalone. But, OTOH, undecorated num doesn't evaluate.

The alternative could be ^num, which at least suggests looking up num, although it suggests not decaying it.

>> block.^num 
== a

What About FENCE! ?

FENCE! generally suggests keyed/valued relationships, and wrapping.

I don't think we generally want lots of code inside a TUPLE! so facilitating code with variables in it via wrapping seems misguided.

foo.{bar}

Anyone got an active imagination? :rainbow: :unicorn:

Just Getting The Conversation Started...

I need the quoting behavior unbinding now, so I'm dropping the literal interpretation. It was never very good for that anyway... foo.'bar: looks too much like an assignment.. So why not have it be an assignment, that unbinds?

1 Like