What Should BLANK! in UPARSE Do?

It's always good to look at history first. So let's compare and contrast #[none] vs. empty block in old Redbols.

In Rebol2 and R3-Alpha, both are no-ops. The input type doesn't matter.

r2/r3>> parse {ab} [[] "a" [] "b" []]
== true

r2/r3>> parse {ab} [#[none] "a" #[none] "b" #[none]]
== true

r2/r3>> parse [a b] [[] 'a [] 'b []]
== true

r2/r3>> parse [a b] [#[none] 'a #[none] 'b #[none]]
== true

In Red, #[none]s are expected to be literal. However, you don't get an error on string inputs...just a failure.

red>> parse {ab} [[] "a" [] "b" []]
== true

red>> parse {ab} [#[none] "a" #[none] "b" #[none]]
== false

red>> parse [a b] [[] 'a [] 'b []]
== true

red>> parse [a b] [#[none] 'a #[none] 'b #[none]]
== false

red>> parse [#[none] a #[none] b #[none]] [#[none] 'a #[none] 'b #[none]]
== true
2 Likes

What Should BLANK! in UPARSE Do?

I've really found that I like BLANK! literally at source level as a way to say SPACE in string operations.

So it could be useful in PARSE for this purpose:

>> parse "aaa bbb" [some "a" _ some "b"]
== "b"

We haven't talked about the "blank and space" duality for a while, but I'd even gone as far to suggest that when you do something like TO BLOCK! of a string it might transform the spaces into blanks:

>> to block! "the cat"
== [#t #h #e _ #c #a #t]

(People might not recall why I was mentioning this, but around the time of UTF-8 Everywhere it was pointed out that since we had non-fixed-size codepoints, seeking in strings and mutating them could be costly. So if you had a string algorithm you might want to "explode" a string into a BLOCK! representation to work on it. This would give you great flexibility to do things like put in substitutions with full strings, or mark the cells with intermediate states for your algorithm...and then you would collapse it all down at the end by turning it back into a string.)

The Literal Interpretation Is Also Compelling in Arrays/Sequences

I've thought of BLANK! as being the analogue to space in blocks, so matching them literally there makes sense:

>> parse [a a a _ b b b] [some 'a _ some 'b]
== 'b

But where it really shines is in processing things like paths and tuples, to match the gaps in them:

>> refinement-rule: [subparse path! [_ word!]]

>> parse [/foo] [refinement-rule]
== 'foo

That's a slam dunk. So now we have the behavior tied up. :relieved:

1 Like