Monadic Call/CC?

Richard Uhtenwoldt ru@river.org
Thu, 21 Feb 2002 14:14:28 -0800


Ashley Yakeley writes:

>    instance PeirceMonad IO where
>        {
>        peirceM foo = do
>            {
>            ref <- newIORef Nothing;
>            catch (foo (\a -> do
>                {
>                writeIORef ref (Just a);
>                ioError (userError "break");
>                }))
>                (\ex -> do
>                {
>                ma <- readIORef ref;
>                case ma of
>                    {
>                    Just a -> return a;
>                    _ -> ioError ex;
>                    };
>                })
>            }
>        };
>
>So you can do it if you have refs and throw/catch for your monad. I think.

In Scheme, the reified continuation can survive the end of
the execution of the call/CC construct, like the continuation survives
that gets put into the variable upward in the following:

> (define (putstrln x) (display x) (newline))
> (define upward 'placeholder)
> (begin 
    (call-with-current-continuation (lambda (cont) (set! upward cont)))
    (putstrln "zzz") )
zzz
> (upward)
zzz

In case your Scheme is rusty, I'll translate the whole example
into untested Haskell.  Assumes an interactive mode like GHCi's.

>   upward<-newIORef Nothing
> do
    {
    pierceM (\cont-> writeIORef upward (Just cont));
    putStrLn "zzz"
    }
zzz
> do
    {
    (Just cont)<-readIORef upward;
    cont
    }
zzz

I do not know if you can get your definition and my test of it
through the typechecker!
Thinking about typing that last makes my head hurt.

But if you can, I think you'll get an error at the last line instead
of a second "zzz" line because call/cc makes rather severe demmands
on an implementation.  Not something an implementation is likely
to be able to support unintentionally.

Holler if you want me to rewrite the test to be noninteractive.