A very interesting post. Thank you!
I have one question and one comment:
Question: I don’t understand how the ping pong example works. You mention that using coroutines a process needs to yield the ToC, but I don’t see any yielding in the program. What’s going on?
Comment: I think this use of try
will make some of the reported errors cryptic and inaccurate. Because if for example if there is a parse error in the third argument in a function call, the entire function call expression is given up on and instead the parser will try the identifier route.
Instead, you want to do left factoring: parse the common prefixes together and then choose between the function call route (which starts with parens) and simply returning the identifier. try a <|> b considered harmful talks about this topic in length.