I'm...pretty sure (?) this is still the best plan.
So there's a new philosophy I've outlined for why BLANK! exists at all, and its purposes as being a kind of generic "nothing to see, here" is distinct from what might be thought of more as a disruptor like null or an unset variable. It is not related at all to soft failure. Blank is simply a wildcard that you can choose to treat equivalently to an empty series or missing value, without committing to being anything in particular.
I've also mentioned that in some mechanical contexts (like APPEND), we are simply more interested in blank's "thingness" than in its representation of nothingness. So you have to DECAY it or SPREAD it or otherwise interact with it to get it to not act mechanically.
PARSE strikes me as one of the more mechanical contexts.
parse [_ _ _] [repeat 3 _]
And I think the value of having it to represent space in string contexts is probably high.
It may be one of those things where to prevent accidents where you didn't mean it to be interpreted as a space, it shouldn't allow you to use it fetched from a WORD! in the rules. You either use @var
to say "I mean literally a blank" or you can make the rule contain a quoted value.
But It's Important To Point Out There Are Other Tools
Already, a quasi-void acts like an empty rule in source:
>> parse "abc" ["a" ~void~ "b" "c"]
== "c"
And a void antiform does too:
>> rule: if false [<whatever>]
>> parse "abc" ["a" rule "b" "c"]
== "c"
You can think of there being infinitely many voids at any position in a block.
Also already, ~ triggers a failure (though it should probably give a better message):
>> parse "abc" ["a" ~ "b" "c"]
** Error: ~ encountered in parse rule
Speculatively, you can use other quasiwords for failures...though this might wind up being disallowed:
>> parse "ccc" [some "a" | some "b" | ~mismatch~]
** Error: ~mismatch~ in PARSE