It's a bit of a pain to collect alternate rules. For instance:
alternates: copy []
rules: [[some integer!] [3 text!]]
for-each rule rules [
append alternates compose [(rule) |]
]
parse data [alternates]
That will give you alternates as [[some integer!] | [3 text!] |]
But that rule will always succeed...should both the component rules fail to match, it will act as a no-op. Because it's equivalent to [[some integer!] | [3 text!] | []], and [] will always succeed.
You get a similar problem if you go the other way.
for-each rule rules [
append alternates compose [| (rule)]
]
Now you've got a rule that is always a no-op: [| [some integer!] | [3 text!]]. Again, this is equivalent to [[] | [some integer!] | [3 text!]], and this time the [] succeeds before the other rules get a chance.
You can hack around this by starting out with alternates: [false]. This way, you can add the [| (rule)] and it will never run the false. So it works.
Wouldn't a New Meaning for the ANY Combinator be Better?
Having reclaimed ANY it seems it would be perfect for this. Why not:
rules: [[some integer!] [3 text!]]
parse data [any (rules)]
You could leave your block in its regular old form, and use it that way. Dyn-o-mite!
Subtlety: A Different Meaning For BLOCK!s
When you use ANY with a literal block, there's something a bit unusual going on:
>> parse [1 "two" <three>] [some any [integer! text! tag!]]
== <three>
Ordinarily, a block like [integer! text! tag!]
would expect to see three things in sequence. But under the context of ANY, the rules change... it's taking its parameter not as a combinator, but as a BLOCK! by value.
At first I thought this was bad, and we'd have to enforce taking the blocks by value, e.g. as the product of a GROUP!:
>> parse [1 "two" <three>] [some any ([integer! text! tag!])]
== <three>
...or perhaps there'd be some non-pure-BLOCK! way of helping to reassure people that the block wasn't going to be processed by PARSE's default BLOCK! combinator:
>> parse [1 "two" <three>] [some any @[integer! text! tag!]]
== <three>
But we're adults, here. And we're using a language whose whole concept is context-dependent meaning. If you can't cope with the interpretation of blocks changing depending on what you pass the block to, you're in the wrong place.
However, do note that under today's logic, fetching blocks through a WORD! reference will still run them through the BLOCK! combinator. Hence you can't say:
rules: [[some integer!] [3 text!]]
parse data [any rules] ; nope, you have to say [any (rules)]
So you need a group there, for now. I don't have an offhand proof of why a variable fetch in that context should run the block combinator--maybe it shouldn't? It's something to think about.
But long story short: Cool Feature, Use It!