I didn't quite absorb that the following was the case in all PARSEs we know of:
>> parse [a b] [word! word!]
== truthy
>> parse [a b] [word!]
== falsey
>> parse [a b] [word! | word! word!]
== falsey
Distinctly Self-Aware "Terminal Blocks", Could They Be Good?
>> uparse [a b] [word! | word! word!]
== b
I'd argue that there already are "two types of blocks":
-
There are blocks that give a truthy result when they don't reach the end, but don't have any match failures
-
There are blocks that can succeed on every match but not reach the end, but be an overall failure
Right now we know these blocks by context. The main rule block you give to PARSE is of type 2, and so is the block given to an INTO.
It's a very small semantic difference to say that "they're the same kind of block, with the decisions about them being made by their caller". Why not allow them to be different kinds of blocks?
It Would Be Weird If It Propagated
Here's an example of the kind of weirdness you'd get into if we said it wasn't a property strictly of the root blocks, but rather "any block that found itself at the end of a chain":
>> parse [] [[(print "A") | (print "B")] [(print "C") | (print "D")]]
A
C
D
Being a "category 2 block", we see how the outer rule block would be creating some irritating asymmetry by saying that any block that knew it wasn't going to reach the end got the privilege.
So I definitely don't like that.
But I'm suggesting a sticky property of blocks, that they effectively already had, being allowed to influence one thing besides whether they are forced to reach the end to succeed... that those blocks also get to try all their alternates before saying they failed.
It's like because they're under more pressure they are given a resource to fall back on to succeed
Looking for Reasons Why It Would Break
It definitely benefits cases like how I was writing CIRCLED, and now that I think about it I've certainly encountered others.
It does break a kind of universality of understanding, like:
rule: [word! | word! word! (print "breaks faith this can never print")]
Yet the understandings in the PARSE world are a little fuzzy. You might say the existing paradigms break the understanding that if that rule came across [a b] as input that it would succeed. It won't if it's an outermost block...
The new understanding would be "Common subsequences in your rule may wind up being matched alternately in top-level parse contexts." If you don't want it, you have an out...double up your block!
rule: [[word! | word! word! (print "breaks faith this can never print")]]
Now your rule won't be subject to the toplevel alternates exception...if you can think of a really good reason why you wouldn't want it.
But, UPARSE is Configurable, So Why Worry Too Much?
I might like it, and other people might not. So we'll see.
I think I'm at least going to try it out, because it looks like it serves common tasks. I'll get some more data and report back.