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

Desugaring of camlp4 quotations of labeled patterns duplicates variables #4886

Closed
vicuna opened this issue Oct 3, 2009 · 3 comments
Closed

Comments

@vicuna
Copy link

vicuna commented Oct 3, 2009

Original bug ID: 4886
Reporter: @yallop
Assigned to: @garrigue
Status: closed (set by @damiendoligez on 2015-01-09T18:42:38Z)
Resolution: suspended
Priority: normal
Severity: minor
Version: 3.11.1
Target version: undecided
Category: -for Camlp4 use https://github.com/ocaml/camlp4/issues
Monitored by: @ygrek

Bug description

Here's a function that extracts the label from a typed labeled pattern:

open Camlp4.PreCast

let extract_label = function
| <:expr< fun ~ ($lab$:$$) -> $$ >> -> lab

Here's what happens when you try to compile it:

$ ocamlc -I +camlp4 -pp camlp4of -c patt.ml
File "patt.ml", line 4, characters 11-14:
Error: Variable lab is bound several times in this matching

This is surprising to the user because 'lab' only appears once in the pattern in the source file.

Here's the camlp4 output, showing that the variable 'lab' has been duplicated:

$ camlp4of patt.ml
open Camlp4.PreCast

let extract_label =
function
| Ast.ExFun (,
(Ast.McArr (
,
(Ast.PaLab (, lab,
(Ast.PaTyc (
, (Ast.PaId (, (Ast.IdLid (, lab)))), _)))),
(Ast.ExNil _), _)))
-> lab

Here's where I think the duplication occurs in the camlp4 source:

    | "~"; "("; i = a_LIDENT; ":"; t = ctyp; ")" ->
        <:patt< ~ $i$ : ($lid:i$ : $t$) >>

    (camlp4/Camlp4Parsers/Camlp4OCamlParser.ml)
@vicuna
Copy link
Author

vicuna commented Sep 18, 2012

Comment author: @garrigue

I think there is no bug here, but a misunderstanding about label syntax:
fun ~(lab:typ) -> exp
is an abbreviated syntax equivalent to
fun ~lab:(lab:typ) -> exp
and they share the same abstract syntax representation.
For this reason, if you want to get the label, you should just write:
<:expr< fun ~$lab$:$$ -> $$ >>
(Not checked)

@vicuna
Copy link
Author

vicuna commented Jul 10, 2013

Comment author: @damiendoligez

Jacques, your suggestion doesn't work, it gives a syntax error. I think it's because of a bug in camlp4: around line 659 in camlp4/Camlp4Parsers/Camlp4OCamlParser.ml, we have :

labeled_ipatt:
  [ [ i = a_LABEL; p = patt LEVEL "simple" ->
        <:patt< ~ $i$ : $p$ >>
    | "~"; i = a_LIDENT -> <:patt< ~ $i$ >>
    | "~"; "("; i = a_LIDENT; ")" ->
        <:patt< ~ $i$ >>
    | "~"; "("; i = a_LIDENT; ":"; t = ctyp; ")" ->
        <:patt< ~ $i$ : ($lid:i$ : $t$) >>

As far as I can tell, the first case is missing the ":" token between the label and the pattern. Also, the label is given as a a_LABEL token, not a ~ followed by a a_IDENT, so I don't know how to make this work.

Can any camlp4 specialist confirm this?

@vicuna
Copy link
Author

vicuna commented Jan 9, 2015

Comment author: @damiendoligez

Transferred to camlp4/camlp4#69

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

2 participants