megaparsack icon indicating copy to clipboard operation
megaparsack copied to clipboard

Documentation: megaparsack doc confusing regarding backtracking

Open bobduff opened this issue 3 years ago • 2 comments

(I'm new to racket and to megaparsack. Both look very interesting. Please let me know if I'm sending this bug report in a wrong way. I already reported this at racket/issues, but was told to go here.)

I think there are bugs in the megaparsack documentation, regarding backtracking.

I'm using racket v8.2 on x86_64 linux.

"2.1.2 Backtracking with caution" says:

> (parse-result! (parse-string try-labeled/p "the integer: false"))
string:1:13: parse error
  unexpected: f
  expected: integer

And then says that message is "useless". In fact, that error message is crystal clear. It then shows how to factor out "the ", and shows a supposedly better error. But the better message is identical to the one above.

This leaves me confused about what backtracking in Megaparsack actually does.

"5.1 Primitives" says:

(or/p parser ...+) → parser?

  parser : parser?

Tries each parser in succession until one either succeeds or consumes
input, at which point its result will be returned as the result of the
overall parse. Parsers that consume input but fail will halt further
parsers from being tried and will simply return an error; if
backtracking is desired, the parser should be wrapped with try/p.

Changed in version 1.5 of package megaparsack-lib: Changed to always
return the first successful result, rather than continuing to try
parsers until one consumes input. The new behavior is more predictable
and more consistent with existing Parsec implementations, though the old
behavior was more consistent with the presentation in the original
paper.

First, it seems strange to document the old behavior first, and then say it changed. Why not document the behavior of the latest version, and then say, "This changed in version 1.5 of package megaparsack-lib; before version 1.5, it did so-and-so..."? (I see that "many+/p" is documented that way.)

Second, the description of the new behavior is incomplete -- it doesn't say what happens if all alternatives of "or/p" fail. Does it return the first successful, but if there is no such, the first unsuccessful (i.e. the first)? That would explain my confusion about section 2.1.2.

"5.1 Primitives" says:

void/p : (parser/c any/c void?)

A parser that always succeeds and always returns #<void>.

"...and does not consume input", right?

"5 API Reference" is missing "into": "syntax objects" should be "syntax objects into".

bobduff avatar Jul 22 '21 15:07 bobduff

First, it seems strange to document the old behavior first, and then say it changed. Why not document the behavior of the latest version, and then say, "This changed in version 1.5 of package megaparsack-lib; before version 1.5, it did so-and-so..."? (I see that "many+/p" is documented that way.)

From what I can tell, what is documented first for or/p is the new behaviour: https://github.com/lexi-lambda/megaparsack/compare/v1.4...v1.5

The note below that seems to be a clarification for the old behaviour that isn't mentioned anywhere, so that section is still definitely confusing.

tfidfwastaken avatar Aug 04 '21 18:08 tfidfwastaken

From what I can tell, what is documented first for or/p is the new behaviour: v1.4...v1.5

Ah, OK, I see how you can read it that way.

The note below that seems to be a clarification for the old behaviour that isn't mentioned anywhere, so that section is still > definitely confusing.

I was confused. ;-)

I guess the stuff in 2.1.2 is obsolete.

Thanks for checking.

  • Bob

bobduff avatar Aug 04 '21 20:08 bobduff