[b] 2014 Feb 03
[m] 2014 Feb 03

Exceptions: SML vs OCaml

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:

1 in SML

$ 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:

1 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 = <fun>
#
  exception E;;
exception E
#
  let e2 = E;;
val e2 : exn = E
#
  let is_e2 = function
    | E -> true
    | _ -> false;;
val is_e2 : exn -> bool = <fun>
#
  is_e1 e1;;
- : bool = true
# is_e1 e2;;
- : bool = false
# is_e2 e1;;
- : bool = false
# is_e2 e2;;
- : bool = true
#

The first difference seems to appear with this example:

2 in SML

$ 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:

2 in OCaml, A

$ 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:

2 in OCaml, B

#
  let f () =
    let module M = struct exception E end in
    (M.E, function M.E -> true | _ -> false)
  ;;
val f : unit -> exn * (exn -> bool) = <fun>
#
  let e1, is_e1 = f ();;
val e1 : exn = E
val is_e1 : exn -> bool = <fun>
#
  let e2, is_e2 = f ();;
val e2 : exn = E
val is_e2 : exn -> bool = <fun>
#
  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.