[MLton] Continuations and MLton.Vector.create

Stephen Weeks MLton@mlton.org
Tue, 28 Mar 2006 14:53:34 -0800


> Isn't it better to either eliminate call/cc (sad) or have an
> implementation that checks the global flag (that used to be there)
> and does something correct, even if horribly slow, in the case that
> call/cc is used?

No.  That is what we used to have, and it caused problems.

I did a little research into the history of callcc and tabulate in
MLton.  callcc was added on April 2, 1999.  On August 7, 1999, Henry
sent mail pointing out the bug in Vector.tabulate.  On August 8, I put
in the "usesCallcc" fix.  It lived for several years, until on July
31, 2002, when Matthew pointed out a problem.

  http://mlton.org/pipermail/mlton/2002-July/022159.html

  The bigger problem is the usesCallcc reference to get tabulate to
  work in the presence of callcc.  As best I can make out, because
  String is derived from CharVector (instead of using it's own
  invocation of the sequence functor), then the code for
  CharVector.concat is really the code for Vector.concat -- i.e., the
  polmorphic vector code.  Now, here's the part I don't understand
  fully: under basis-1997, inferSimplify eliminates the usesCallcc
  refernce, but under basis-2002, it does not.  The only difference I
  can see is that under basis-1997 it's in a monomorphic context,
  while under basis-2002 it's in a polymorphic context.  So,
  usesCallcc sticks around for a while, getting past around in
  environments (which seems odd, because it's global) and cascading
  through the optimizations.  It's eventually elminated, but by the
  end, it's thrown enough things off so that the code isn't quite as
  small as it was before.

I responded with:

  http://mlton.org/pipermail/mlton/2002-July/022160.html

  My feeling is that just as we have not attempted to make our basis
  library implementation thread safe, so should we abandon any
  attempts to make the basis library "callcc safe".  It's certainly OK
  with the spec, which doesn't mention callcc or threads.  If somebody
  uses callcc and wants to use tabulate, they'll have to write their
  own version that is callcc safe.

On November 23, 2002, in r1623, Matthew committed the removal of
usesCallcc from tabulate.  It has remained unused there since,
although in looking now I see that there is a vestigial use in
Array2.tabulate (which I now propose to eliminate).

I think the same argument I made in 2002 still applies.  Namely,
usesCallcc can introduce performance problems, and callcc is
incredibly rarely used.  So, as with threads, it doesn't make sense to
punish users of the basis who don't use callcc just because someone
might want to.  I think the argument is much stronger in the case of
callcc than threads, since callcc is much less useful than threads.

So, we don't guarantee that the basis is callcc safe.  If you want to
use callcc, you need to know what you're doing and write your own
callcc-safe wrapper.