[MLton-user] Improved Exn.withEscape

Vesa Karvonen vesa.karvonen at cs.helsinki.fi
Tue Aug 29 11:40:39 PDT 2006


Quoting Stephen Weeks <sweeks at sweeks.com>:
> > It is quite rare to need multiple exitTo invocations in a
> > single function
> 
> Yeah, that one use is the common case is what lead me to
> 
>   val withEscape: (('a -> 'b) -> 'a) -> 'a

Indeed.  I've been using a similar function and changed the design
recently when the idea that to express the notion properly requires
first-class polymorphism occured to me.  (In retrospect it seems
obvious.)  I wrote the note, because I don't recall having seen the
idea been noted earlier (it probably has been).  Shortly after writing
my note, I noticed the connection to callcc.  I had previously (some
years ago) wondered about the signature of callcc (in SML/NJ), but
hadn't realized the typing aspect.

> The point is that in the common case it requires the least verbiage
> 
>   withEscape (fn e => ... e x ...)
> 
> And, it can still be re-polymorphised in exactly the same way as the
> void withEscape, should one need multiple uses.

Obviously one can implement withEscape trivially on top of withLabel and
exitTo:

  fun withEscape f = withLabel (f o exitTo)

Perhaps it would be best to have both available.

Anyway, I think that withLabel + exitTo is the more "primitive" design
and it makes more sense to implement withEscape (with or without Void.t)
on top of withLabel + exitTo rather than vice versa.

> > The withLabel+exitTo approach also parallels the way callcc is often
> > typed in ML (http://mlton.org/MLtonCont).
> 
> Good point.  It just feels like overkill in this case since there
> aren't any other operations on labels other than throw.

Hmm... One could implement an Exit module with the equivalents of
Cont.prepend and Cont.throw', but I'm not sure how useful they would be.

> The overhead
> does go down if one puts withLabel+exitTo at the top level, but it's
> still two functions instead of one, and I'm not sure it's worth going
> to the toplevel in either case (whereas for "dead" or "undefined" it
> pretty clearly is).

I'm not too worried about introducing new nonfix top-level bindings
as long as they define stuff that one could reasonably consider to be
a part of the language (and I tend to think that control constructs
like this qualify for that).

> > I also worry about the efficiency of the implementation.  The
> > withLabel + exitTo approach avoids having to build a closure and is
> > likely to yield slightly better generated code (on any compiler).
> 
> Wrong, at least in the case of MLton.  There will be no closure.  In
> fact, in many cases, MLton will even avoid allocating the exception.

Right.  I should have written "unlikely to generate worse code", but
it just sounds so much weaker... :-)

-Vesa Karvonen



More information about the MLton-user mailing list