Should COMMA! Have An Eval Step?

The COMMA! type is pretty great, and I would definitely be displeased if it went away.

https://rebol.metaeducation.com/t/the-language-worlds-weirdest-comma-mechanic/1387

But how to handle it in the evaluator has raised some questions.

One problem with the evaluator "just skipping it" is that this creates a bad situation in terms of where you're at the end of an evaluation but don't know it, e.g.

eval:step [1 + 2, , ,]

If the evaluator "just skips" commas, then after a step you're at [, , ,] and your next evaluation produces... what?

It gets very convoluted if we can't answer the question of whether you're at the end of the evaluation or not just by seeing if the block is at the tail.

So I think that has to take a step, and it has to produce a product.

We're fortunate to have the answer of a VOID! Which would let people do things like:

>> eval [1 + 2, 10 + 20,]
== 30

Invisible commas at the end might seem like a feature you don't care about, but if you're building code programmatically and trying to separate expressions, it's a pain to worry over not putting commas at the end if you want an expression to fall out.

So I think eval:step [,] has to give VOID! (because it wasn't at what we could detect as an END). And in order to synthesize a product it can't give you a position of NULL, it has to give you back a next position of [] (which when you eval will give you null to indicate "no product, not even void".)

Hence any commas before tail are beholden to the rules, that if you're not at the tail you have to take at least one eval step and give the tail.

So, "are any other commas more optimized".

If you optimize out commas, then an evaluator couldn't go one step at a time with:

[, , , , 1 + 2, , , , 10 + 20, , ,]

You'd presumably see COMMA!, then do an eval step and synthesize 3 and be positioned before the comma after the 2, then do an eval step and synthesize 30 and be positioned before the comma after the 20, and then do another step and get a void and be at the tail.

Hopefully I'm being clear here. The issue is you can't always have the evaluator skip commas. And if you sometimes skip, you're creating a weird situation.

The Reason This Is Under The Optimization Category...

There's a sane and simple answer. Which is: COMMA! evaluates to VOID!

This means you get to see every step, and control it. If there were RebindableSyntax for COMMA! you could give it all new behavior in some contexts.

It seems like the right and wholesome answer. But it means that if you use commas, you're slowing things down. This might bother people to where they wouldn't use the comma even if they want to...whereas they would have been fine using it if the evaluator just skipped them (and did one VOID! evaluation at the tail, if any happened to be at the tail).

My feeling is that you should have to request EVAL:SKIP-COMMAS or similar if you don't want to generate VOID!s on each step.

Generating one-void-per-comma is the right answer for the general case.

1 Like

For the sake of completeness, I should point out there is a possible answer which doesn't have COMMA! producing VOID!...

>> eval:step [, , ,]
** PANIC: Evaluation cannot be all COMMA!s

If we simply prohibit all COMMA! evaluations, then the evaluator could always skip commas before an evaluation and after it.

But each comma producing a VOID! is cleaner.