The "Yada Yada Yada" Operator (...)

It seemed we could have a shorter way to say to <end> (or thru <end>, they act the same).

 >> parse "aabbcc" [some "a" to <end>]
 == ""

In fact, what you want more often is probably elide to <end>. Because the <end> combinator currently evaluates to the end position of the series (hence the "" you see above, as the TO returns what its argument evaluates to.)

 >> parse "aabbbcc" [some "a" elide to <end>]
 == "a"

A kind of obvious choice for meaning this would be ...

 >> parse "aabbbcc" [some "a" ...]
 == "a"

(Initially I was skeptical of using ... without some decoration, and did this with the TAG! of <...>, but I think the reasons I was skeptical are probably not good reasons, and we should go ahead and make it easier on the eyes and easier to type.)

But Why Should It Only Work At The End?

This seems useful:

 >> parse "aabbbcc" [... some "b" ...]
 == "b"

But isn't that just a synonym for THRU, with the exception that if there's nothing to go THRU it assumes you mean <end> ?

Well, a synonym for THRU isn't really what you want. You'd probably like this to work:

 >> parse "aabbbcc" [... some "x" | some "b" ...]
 == "b"

In essence, you want it to implicitly wrap anything to the right--up to the next <...>--in a BLOCK!, so act equivalently to:

 >> parse "aabbbcc" [thru [some "x" | some "b"] elide to <end>]
 == "b"

That's not possible for a normal combinator, you'd need a variadic one.

Today's approximation of variadic combinators is to just special-case the implementation directly in the BLOCK! combinator.

So...that's what I've done!

A more elegant way of writing the feature may come down the pipe someday. But this gives us a version we can use in the here and now.

It's experimental, so use with caution.

:man_scientist:

2 Likes

This particular point is actually debatable: the question is kind of one about precedence. e.g. does ... outrank |

[... some "x" | some "b" ...]

Could mean either of these two things:

[[... some "x"] | [some "b" ...]]

[... [some "x" | some "b"] ...]

But then we have to look at the situation where there is no | involved:

[... some "x" some "b" ...]

I feel like that shouldn't be up for debate. e.g. I don't think that should be read as equivalent to:

[[... some "x"] some "b" ...]

Because then it would fail on:

"aaaxxxxaaaaxxxbbbccc"

I feel like the ... should not be finding some "x", consider it a match, and then kick over to some "b" and fail... when there were [some "x" some "b"] still to be found in the series.

So the point stands that ... shouldn't be thought of as "taking a parameter of the next rule" but has to be variadic. The question is should that variadicness stop when it sees a | or just another ...

One argument for having it mean the latter is that the former can be accomplished with THRU.

Consider trying to write something that would match file extensions:

is-rebol: did parse filename [thru [".reb" | ".r3" | ".r"]]

If ... were able to subsume |, you can get something briefer:

is-rebol: did parse filename [... ".reb" | ".r3" | ".r"]

But it has a downside, in that if we were to write it as a more well-behaved variadic combinator, it may be that out-prioritizing the | is not an approved behavior.

I kind of feel now, looking at it, that the | divides things into sections...and it seems like the <...> is visually bounded within the first section. So we wouldn't think of it as having a connection to the others.

So if we're going just based on the visuals, it probably needs to stop variadic consumption when it hits a vertical bar. :-/

But hey, we have a lot of tools these days!

is-rebol: did parse filename [... any [%.reb %.r3 %.r]]
1 Like