Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange camlp4 rewrite #5837

Closed
vicuna opened this issue Nov 28, 2012 · 4 comments
Closed

Strange camlp4 rewrite #5837

vicuna opened this issue Nov 28, 2012 · 4 comments

Comments

@vicuna
Copy link

vicuna commented Nov 28, 2012

Original bug ID: 5837
Reporter: elnatan
Status: closed (set by @damiendoligez on 2015-01-13T18:32:36Z)
Resolution: suspended
Priority: normal
Severity: minor
Version: 4.00.1
Target version: undecided
Category: -for Camlp4 use https://github.com/ocaml/camlp4/issues

Bug description

camlp4 rewrites 'let r = ref run () -> ()' in a strange way:

$ camlp4o -printer Camlp4OCamlPrinter -str 'let r = ref fun () -> ()'
let r = ref

let _ = fun () -> ()

Steps to reproduce

$ echo 'let r = ref fun () -> ()' >foo.ml
$ ocamlc -i foo.ml
File "foo.ml", line 1, characters 12-15:
Error: Syntax error
$ ocamlc -pp camlp4o -i foo.ml
val r : 'a -> 'a ref

@vicuna
Copy link
Author

vicuna commented Nov 28, 2012

Comment author: @bobzhang

this is syntax ambiguity here
either
let r = ref ;;
let _ = fun () -> () ;;
or
let r = ref (fun () -> ()) ;;

since ";;" is optional

@vicuna
Copy link
Author

vicuna commented Nov 28, 2012

Comment author: elnatan

Your second alternative is still ambiguous. You need extra parentheses to remove the ambiguity:

let r = (ref (fun () -> ()));;

In any case, it seems clear that either camlp4 or ocamlc should change to match the other one.

@vicuna
Copy link
Author

vicuna commented Dec 3, 2012

Comment author: @gasche

OCaml and Camlp4 both reject "ref fun () -> ()" as an expression, despite it being correct according to the hand-wavy context-free grammar of the manual. The problem is that Camlp4 is then clever enough to turn the ambiguity on its head and parse something different, while OCaml's different parsing technology plainly rejects this case.

It's hard to say that Camlp4 is "wrong" in this case, as its resulting parsing is valid as per the grammar rules, and it cannot be faulted for parsing more input than OCaml. However, the parse we really want, if any, would rather be "let r = (ref fun () -> ())", or a rejection of the ambiguity.

I think this is a case where Camlp4 could be changed to mirror OCaml's behavior. However, changing Camlp4's parser is subtle and can have unintented consequences. My own guess it that is a case of "too hard and too risky to fix", and I'm preparing to close the bug as "won't fix" in a medium-term future if nobody acts.
Hongbo or Jérémie, if you disagree with my assessment of the situation or know how to fix this properly, please feel free to take this one!

PS: while a "fun ..." is rejected on the right of an application, it is accepted as a second argument of an infix operator by both OCaml and Camlp4. That is very convenient for monadic-style syntax: "foo >>= fun x -> ..." doesn't need a terminal delimiter, and therefore allows the same style as "let .. in .. ".

@vicuna
Copy link
Author

vicuna commented Jan 13, 2015

Comment author: @damiendoligez

Transferred to camlp4/camlp4#77

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant