Double Negation in PARSE is NOT NOT NOT Cool

You keep your money in Yen? :slight_smile:

I don't know that people would comprehend the difference between UNLESS vs. NOT.

If we're looking for uniform operators, it seems there are NOT-AHEAD and ONE-IF-NOT-AHEAD, where ONE-IF-NOT-AHEAD simply takes the next single item if the rule doesn't match:

>> parse ["a"] [one-if-not-ahead [integer! integer!]]
== "a"

This ONE-IF-NOT-AHEAD operator is kind of clunky, though similar to how SET works in Rebol2/Red, to take the first item of a match (vs UPARSE's last synthesized product of "a block combinator").

rebol2>> parse ["a" "b"] [set x [string! string!]]
== true

rebol2>> x
== "a"

one-if-not-ahead rule is simply [not-ahead rule, one] (in the current ONE-is-historical-SKIP model)

It would work with anything... but I'd personally rather have a NOT that wasn't compatible with everything, but covered common cases. And if someone actually wanted ONE-IF-NOT-AHEAD they could write [not ahead rule, one] for themselves.

It wouldn't really be a combinator, but a "combinator modifier".

Let me reiterate it's simply about being able to pass a refinement to combinators, even if they are triggered by a datatype and hence nowhere to put the refinement.

e.g. you can write ahead/not but you can't write #a/not

I think not *combinator* being able to do this modification is a cool idea.

Though of course allowing general "combinator modifiers" creates a lot of obfuscations, due to the backchannel. If I'm trying to make a debugger, then these refinements slipping in have to be presented somehow... otherwise once you've stepped into the not and all you see is #a it will be confusing when #b looks to be a match of #a.

Maybe negation is the only combinator modifier, so the system can account for it.

Conservative Choice For Now

A conservative thing to do may just be to rename NOT as NOT-AHEAD and work on higher priority tasks.