A small update. 

But before the update, let me clarify the original reason, why the expression `let a = assert false in fun x -> 1` is not generalized. The reason is because the `assert false` is not nonexpansive (sorry for the double negation). A nonexpansive value, in OCaml compiler parlance, is a value that has "no _observable_ side effects". The `assert false` is currently typed as a special expression, that is assumed to have a side effect (i.e., it is expansive).  Thus, it is basically treated the same as `let a = print_int 1 in fun x -> 1` that is also not generalized, as the evaluation of the `print_int 1 in fun x -> 1` has some effect. 

Apparently, the assumption that `assert false` is expansive was too conservative, as it was already subsumed (in some cases) with the value restriction relaxation. So it will be relaxed soon, see GPR#1142 [1]. And soon both of your functions will have the same type. 



[1]: https://github.com/ocaml/ocaml/pull/1142

On Thu, Apr 20, 2017 at 11:13 AM, Kenichi Asai <asai@is.ocha.ac.jp> wrote:
Thank you!  That's very clear.  So instead of writing assert false, if
I could write a "value" of type 'a, then the type of x becomes 'a.

I confirmed it with the following file:

--------------------------------
let v = assert false

let g1 = let a = v in
         let f = fun x -> 1 in
         f

let g2 = let a = assert false in
         let f = fun x -> 1 in
         f
--------------------------------

If I see the types of variables via "ocamlc -i", I obtained:

val v : 'a
val g1 : 'a -> int
val g2 : '_a -> int

Thank you again!

--
Kenichi Asai

--
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs