It’s uncommon to use expressions that evaluate to branches passed to conditionals. And when you do use one, you probably don’t mind putting it in a GROUP! (especially considering that 99% of the time in the far more common cases you were willing to put it in a BLOCK!).
So Ren-C now uses that fact–plus generalized quoting–to allow for a briefer and faster way to evaluate to literals in your conditionals:
>> if true '[block as data] == [block as data]
Simply pass in a QUOTED! item of any kind, and that item will be what a branch evaluates to. It will be one less level of quoting than what you pass in:
>> if true '<tag> == <tag>
Previous attempts to get something like this used an /ONLY refinement. But this lets you mix and match in the same operator, as opposed to switching the operator into a “mode”:
>> either true '[1 + 2] [1 + 2] == [1 + 2] >> either false '[1 + 2] [1 + 2] == 3
It Solves Some Problems for CASE
Historically, CASE was more lax in accepting types than the corresponding IFs would be:
>> case [1 = 1 <foo>] == <foo>
It would allow the by-products of arbitrary evaluation to be used:
>> word: <foo> >> case [1 = 1 word] == <foo>
Sometimes this resulted in double-evaluation:
>> word: [print "surprise"] >> case [1 = 1 word] surprise == true
The dodgy nature of this “may be a double evaluation, may be not” with no way to tell at source level raised some concerns, which are laid out in the “backpedaling on non-block branches” post.
The combination of soft quoting and generalized quoting lets the same patterns that work for IF work in CASE. It lowers the risks in a legible way:
>> case [1 = 1 '<foo>] == <foo>
It’s Faster and More Efficient
Quoting of up to three levels can be done a cell in place. So '[x] costs less storage (and has better locality with the surrounding cells) than [[x]].
Outside of the reduced storage, it’s also lighter on the evaluator.
There were very few pieces of code in the Ren-C repo that were affected. One was a help test. It wanted to generate a real-world block to run, and didn’t want to call DO for some reason:
for-each w words of lib [ dump w if not set? w [continue] if action? get w compose [help (w)] ; errors now...IF thinks the COMPOSE word! is branch else [ help (get w) ] ]
It’s easy enough to change that to
(compose [help (w)])…this kind of usage is very rare.
The one common case of passing code to a conditional originated from Ren-C…the use of lambdas that could take the argument of what drove the conditional:
trap [1 / 0] then error => [print [error]]
So you have to put it in a GROUP!:
trap [1 / 0] then (error => [print [error]])
I think in the scheme of things it’s worth it. And it isn’t like people aren’t used to putting branches in delimiters for blocks anyway!