[MLton] SXML Exceptions

Matthew Fluet fluet@cs.cornell.edu
Thu, 1 Jun 2006 15:12:29 -0400 (EDT)


> I'm having a hard time understanding how exceptions work in the SXML
> phase.

There is one trickiness to exceptions in the SXML intermediate 
representation, as one of the program transformations on that IL is to 
(partially) implement exceptions; see 
mlton/xml/implement-exceptions.{sig,fun}.

It is this pass that transforms the program from having exception 
declarations scattered through the program to having a single exception 
datatype; having the whole program allows the extensible exception 
datatype to be implemented with a (non-extensible) datatype, as all 
possible variants may be identified.  The transformation does other things 
as well, including implementing exception history.

> Specifically, can I get an explanation of the fields of
> Raise of {exn: VarExp.t, extend: bool}?

The exn field is simply the variable to which the exception to be raised 
is bound.  The extend field determines whether or not this raise 
expression should extend the exception history or start a new exception 
history.  The reason to distinguish these cases is that a source SML 
expression like

   e handle Overflow => eo | Match => em

is first translated to something like:

   e handle exn => (case exn of Overflow => eo | Match => em
                           | _ => raise exn)

We don't want the implicit re-raising of an exception to start a new 
exception history; so the re-raising 'raise' has extend = true.

> My current understanding is that exceptions are declared in decs of an
> Exp, and any Raise must occur in the try field of a Handle. I'm not sure
> of the purpose of extend. Is this on the right track?

Before the implement exceptions pass, exceptions are declared as decs in 
an expression, but after that pass, the Exception variant of the Dec.t 
datatype is not allowed.  (However, this is not checked by the XML/SXML 
type checker.)

Before and after the implement exceptions pass, Raise may occur anywhere, 
not necessarily in the static (or dynamic) scope of a Handle expression.
The dynamic behavior matches that of SML -- a raise transfers control to 
the nearest dynamically enclosing handler, which then either handles the 
exception or re-raises.