2014-02-03
Bob Harper has mentioned that exceptions in OCaml aren't done right, that SML's dynamic classification is uniquely superior. This intrigued me, so I set out to find some concrete examples demonstrating this uniqueness. I was not able to.
Here're a couple of examples demonstrating the generative semantics of SML exceptions (derived from http://mlton.org/GenerativeException) followed by their analogues in OCaml:
$ ledit sml Standard ML of New Jersey v110.76 [built: Tue Jan 7 12:24:04 2014] - - exception E; exception E - - val e1 = E; val e1 = E(-) : exn - - fun isE1 E = true = | isE1 _ = false; val isE1 = fn : exn -> bool - - exception E; exception E - - val e2 = E; val e2 = E(-) : exn - - fun isE2 E = true = | isE2 _ = false; val isE2 = fn : exn -> bool - - isE1 e1; val it = true : bool - isE1 e2; val it = false : bool - isE2 e1; val it = false : bool - isE2 e2; val it = true : bool -However, this behavior is identical in OCaml:
$ ledit ocaml OCaml version 4.01.0 # exception E;; exception E # let e1 = E;; val e1 : exn = E # let is_e1 = function | E -> true | _ -> false;; val is_e1 : exn -> bool =The first difference seems to appear with this example:# exception E;; exception E # let e2 = E;; val e2 : exn = E # let is_e2 = function | E -> true | _ -> false;; val is_e2 : exn -> bool = # is_e1 e1;; - : bool = true # is_e1 e2;; - : bool = false # is_e2 e1;; - : bool = false # is_e2 e2;; - : bool = true #
$ ledit sml Standard ML of New Jersey v110.76 [built: Tue Jan 7 12:24:04 2014] - - fun f () = = let = exception E = in = (E, fn E => true | _ => false) = end; val f = fn : unit -> exn * (exn -> bool) - - val (e1, isE1) = f (); val e1 = E(-) : exn val isE1 = fn : exn -> bool - val (e2, isE2) = f (); val e2 = E(-) : exn val isE2 = fn : exn -> bool - - isE1 e1; val it = true : bool - isE1 e2; val it = false : bool - isE2 e1; val it = false : bool - isE2 e2; val it = true : bool -Whereas in OCaml an analogous definition does not seem to be possible:
$ ledit ocaml OCaml version 4.01.0 # let f () = let exception E in (E, function E -> true | _ -> false) ;; Error: Syntax error #But with some local module hackery, we can:
# let f () = let module M = struct exception E end in (M.E, function M.E -> true | _ -> false) ;; val f : unit -> exn * (exn -> bool) =# let e1, is_e1 = f ();; val e1 : exn = E val is_e1 : exn -> bool = # let e2, is_e2 = f ();; val e2 : exn = E val is_e2 : exn -> bool = # is_e1 e1;; - : bool = true # is_e1 e2;; - : bool = false # is_e2 e1;; - : bool = false # is_e2 e2;; - : bool = true #
Which seems to behave identically to SML.
Am I wrong? Please let me know!