UPARSE is shaping up to be mostly uniform, in that most arguments to parsers take parsers...which are functions (that in turn take other parsers)
The job of the parse engine is to take sequences of words and symbols and turn them into these functions. This is why you can write some keep integer! or some [keep integer!] or some [keep [integer!]]. It's not the job of SOME or KEEP or INTEGER! to worry about these blocks.
There are not a lot of cases of breaking this rule. But the Redbol emulator has to, in order to get things like:
set x integer!
Here we see that X is basically being "quoted" by SET. It is not a parser in its own right. While the second parameter (integer!) is a parser, and could just as easily be [some integer!].
Right now the way I'm dealing with this is to say that arguments which are not parser functions, like the variable here, are quoted arguments. If in the combinator spec it sees a quoted argument, it just gets it literally.
So clearly that's important for legacy features. But does it have a place in the harmonious parse world going forward?
Well, right now the SEEK rule is using it.
x: here ; here is a rule...which is value-bearing with the current position
some "a"
seek x ; hm, here we are at another one of those quoting non-rule variables
Should this be shuffled around to where SEEK takes a rule? If so, this would be:
x: here
some "a"
seek (x)
Because GROUP! is set up as a rule that always succeeds, and bears the value of its evaluation.
This kind of formulation would imply you could also do something like:
seek [some "a", let pos: here, some "b", (pos)]
So GROUP! would not be the only thing you could put there. Whereas if we went with the quoting-variable-option, you'd be locked into only putting words there.
...But it's a Bigger Question Than Just SEEK
I've talked about maybe having a parse exposure of enbin and debin. Could they look like:
uparse #{1020} [x: debin [BE + 2]] ; BE + 2 block is obviously not a "rule"
Might the DEBIN take a BLOCK! to not mean a rule at all, but be literal dialect data to tell it to be "big-endian, unsigned, 2 bytes"? Or would such values always need to be passed to rules via GROUP! ...so you know they're not rules?
uparse #{1020} [x: debin ([BE + 2])]
As I say, the ability to read arguments quoted literally will be there, else we could not implement Redbol SET and COPY emulation. The feature of combinators taking arguments by quote is a given.
But is it a good idea to have anything in the box that does this, and encourage the practice?
I Think Flexibility Should Be Taught (Possibly (?) Encouraged?)
This reminds me a lot of the questions raised over speaking with Tics.
There I asked if there should be expressions type of x instead of 'type of x, or if it was setting a bad example.
When something is so common and you get stuck making it ugly...when it would be very learnable and natural to make it nicer, I don't see why you would want the ugly version.
It's debatable how much of this applies to DEBIN. You're more likely to want to make a rule for uint16:
uint16: [debin ([BE + 2])]
uparse #{1020} [x: uint16]
Which may even challenge my "does this need to be a combinator anyway":
uint16: [let data: across 2 skip, (debin [BE + 2] data)]
uparse #{1020} [x: uint16]
Though that's less efficient, as it has to create a new series vs. decoding the binary input directly. But at least these things are becoming possible. It's a step up.
The bigger point remains: I think if someone has an idiom that they like, telling them "all BLOCK!s in PARSE must be rules, and you have to put them in GROUP!s to pass as arguments" feels like a restriction on par with saying that you must pass QUOTED! values to any regular functions...that there are no implicitly quoted arguments.
Implicitly quoted arguments seem to me to be one of the things that makes the language able to shapeshift to let you build syntaxes on par with coming up with a new language. It's not something we want to overuse, but not using it at all seems misguided.
So I think this same thing happens with PARSE.