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

small bug in relaxed value restriction #4862

Closed
vicuna opened this issue Sep 9, 2009 · 5 comments
Closed

small bug in relaxed value restriction #4862

vicuna opened this issue Sep 9, 2009 · 5 comments
Assignees
Labels

Comments

@vicuna
Copy link

vicuna commented Sep 9, 2009

Original bug ID: 4862
Reporter: lavi
Assigned to: @garrigue
Status: closed (set by @garrigue on 2010-06-08T02:45:58Z)
Resolution: fixed
Priority: normal
Severity: minor
Version: 3.11.1
Fixed in version: 3.12.0+dev
Category: ~DO NOT USE (was: OCaml general)

Bug description

Vraiment pas important, mais il me semble que le programme suivant devrait être accepté:

# type t = {f: 'a. ('a list -> int) Lazy.t}
  let l : t = { f = lazy (raise Not_found)};;
Characters 62-84:
    let l : t = { f = lazy (raise Not_found)};;
                      ^^^^^^^^^^^^^^^^^^^^^^
Error: This field value has type ('a list -> int) Lazy.t
       which is less general than 'b. ('b list -> int) Lazy.t

Le type de f ('a Lazy.t) pourrait pourtant bien être généralisé. D'ailleurs, si l'on passe par une variable intermédiaire, ça passe:

type t = {f: 'a. ('a list -> int) Lazy.t}
let tmp = lazy (raise Not_found)
let l : t = { f = tmp }
@vicuna
Copy link
Author

vicuna commented Sep 9, 2009

Comment author: @garrigue

Je comprends votre confusion, mais cet exemple n'est pas un bug, meme si il demontre la fragilite de la relaxed value restriction dans certains cas.
En effet le type de [lazy (raise Not_found)] n'est pas le meme quand on le met directement dans l'enregistrement ou lorsqu'on definit une valeur intermediaire.
Dans le premier cas, la contrainte de type induite par l'enregistrement donne le type
[('a list -> int) Lazy.t] qui n'est pas generalisable suivant la restriction relaxee (occurence contravariante).
Dans le second cas c'est ['a Lazy.t] qui est lui generalisable (occurence covariante).
Ce genre de phenomene n'est pas rare, et c'est donc une bonne idee d'utiliser un let explicite pour aider le typeur. On pourrait en theorie retarder l'application de la contrainte de type pour pouvoir mieux generaliser, mais ca risquerait d'induire des messages d'erreur moins clairs.

@vicuna
Copy link
Author

vicuna commented Sep 9, 2009

Comment author: lavi

Hum ça reste bizarre, parce que le code suivant ne passe pas non plus :

# type t = {f: 'a. ('a list -> int) Lazy.t}
  let l = { f = let tmp = raise Not_found in tmp };;

pour le coup, c'est la première fois que je vois le type changer selon que l'on utilise un "let" ou un "let in"...
(ceci n'est évidemment pas grave, et ne me gène aucunement dans ma programmation en caml, qui reste un merveilleux langage !)

@vicuna
Copy link
Author

vicuna commented Sep 9, 2009

Comment author: lavi

oups typo:

let l = { f = let tmp = lazy (raise Not_found) in tmp };;

mais ça reste vrai: si on sort le "let tmp", ça passe...

@vicuna
Copy link
Author

vicuna commented Apr 27, 2010

Comment author: @garrigue

Je ne vois pas de solution simple: le problème vient du fait qu'on propage le type attendu vers
l'expression à typer, ce qui rend impossible de généraliser une variable devenue contravariante.
La seule option ici semble être de backtracker, pour retyper sans propagation...

@vicuna
Copy link
Author

vicuna commented Jun 8, 2010

Comment author: @garrigue

Fixed in version/3.12, revision 10538.
Used backtracking, but as long as one doesn't nest polymorphic record expressions, this shouldn't cause an exponential behaviour,

@vicuna vicuna closed this as completed Jun 8, 2010
@vicuna vicuna added the bug label Mar 20, 2019
garrigue added a commit to COCTI/ocaml that referenced this issue Jan 24, 2024
garrigue added a commit to COCTI/ocaml that referenced this issue Jan 24, 2024
garrigue added a commit that referenced this issue Jan 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants