Unit refs....

Stephen Weeks MLton@research.nj.nec.com
Wed, 16 Feb 2000 15:55:34 -0800 (PST)


> I'm actually not using exceptions, and I could get by with non-generative
> ones if I had to.. can you give me a hint as to how to remove generative
> exceptions?

The right pass to change is xml/implement-exceptions.fun.  Here's an
example input and output of the pass.

----------------------------------------
exception Foo
exception Goo of int
val f = Foo
val g = Goo 13
... case x of
       Foo => e1
     | Goo y => e2
     | _ => e3
----------------------------------------

----------------------------------------
datatype exn = 
   Foo of unit ref
 | Goo of unit ref * int

val fooRef = ref()
val fooVal = Foo(ref())
val gooRef = ref()
val f = fooVal
val g = Goo(gooRef, 13)
... let fun default() = e3
    in case x of
       Foo r => if r = fooRef then e1 else default()
     | Goo(r, y) => if r = gooRef then e2 else default()
     | _ => default()
    end 
----------------------------------------

It shouldn't be too hard to change the pass to produce the following.

----------------------------------------
datatype exn = 
   Foo
 | Goo of int

val fooVal = Foo
val f = fooVal
val g = Goo 13
... case x of
       Foo => e1
     | Goo y => e2
     | _ => e3
----------------------------------------

I'm a bit confused, though, since I thought you weren't using MLton's
basis libray.  If you're not, then I don't see how you would get any
exceptions in your program other than Match and Raise, which are
introduced by the pattern match compiler.

I'd like to be sure that exceptions are really the cause of the
problem before changing the pass.  And even if they are, this is still
a pretty bad solution, since it changes the semantics of the program.
I'm sure that there are SML programs out there that would break
(including MLton itself).