Local modules are usually "safe" in the sense that the type system checks that the local types do not escape the whole expression. # let test = let module Local = struct type t = Foo end in Local.Foo;; Error: This `let module' expression has type Local.t In this type, the locally bound module name Local escapes its scope However, exceptions do not create a local type, they instead augment the global open-ended "exn" type, so the type-checker won't detect the leak. Finally, you don't want to disallow local exception declarations, as they're very useful in various situations -- simply moving an existing module to a local scope. The use of the new (type t) construct to declare local polymorphic exceptions is also useful in some cases. See for example: http://ocaml.janestreet.com/?q=node/18#comment-190 (I agree that the type regression when escaping is quite weird and should be avoided if possible.) On Wed, Jan 26, 2011 at 11:17 PM, Jim Pryor > wrote: > I expect this is bad coding style, and should not be relied on. However, > I was surprised at the behavior, and wondered whether it was intended: > > # let f = fun (type t) x -> > let module M = struct exception E of t end in > M.E x;; > val f : 'a -> exn = > > f is polymorphic, as we expect: > > # f 1;; > - : exn = E 1 > # f "s";; > - : exn = E "s" > > But now notice: > > # f ();; > - : exn = E 0 > # f None;; > - : exn = E 0 > > It appears that non-heap values are always getting magicked into ints. > > Has this been noted before? > > -- > Jim Pryor > profjimm@jimpryor.net > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa-roc.inria.fr/wws/info/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > >