What should evaluating an empty block (`EVAL []`) do?

(Note: I've pared the above conversation down to the minimum, updating it with 2024 terminology and behaviors.)

There's a few interesting developments that inform the thinking on this...

Passing TRASH to Comparison Operations Now Fails

>> if (10 = get/any $asdf) [print "Not legal in Ren-C"]
** Script Error: = expects [something?] for its value2 argument

This decision aligns with Rebol2's treatment of UNSET! in comparisons (though Red and R3-Alpha allow it).

FUNC returns TRASH unless you use an explicit RETURN

A side effect of this is that it's a lot harder to accidentally return VOID from a function:

 whatever: func [x [block! group!]] [
     if block? x [append x spread [a b c]]
     if group? x [append x spread [d e f]]
 ]

Under the historical behavior, if you pass in a GROUP! the final function result would be the branch result of the APPEND which will be the group with [d e f] added. But if you passed in a BLOCK! then the IF GROUP? test would be false and the overall return result would be a VOID.

VOID Is An Unstable Antiform

  • Cannot store in variables

  • Ilegal in comparisons

  • Illegal in isolated conditional testing

  • Opts-out when testing conditionally in aggregate (e.g. ANY and ALL).

FUNC Change Means The World Overall Is More Full Of Trash

In this case it's a good thing. The fewer accidental VOIDs that are being produced in the ecology overall, the better I feel about constructs like EVAL being willing to produce them, or for things like REDUCE (or anything else) being willing to discard them.

Honestly, It's Barely Come Up... Yet

Which is an indication it doesn't happen on accident. So the main way it's going to come up is if people know that's the behavior, and start designing code that purposefully uses the pattern.

And if they do that, then that is a good thing, because they're getting use out of it?