[racket-dev] Changing call/cc

From: Asumu Takikawa (asumu at ccs.neu.edu)
Date: Tue Sep 4 00:45:05 EDT 2012

On 2012-08-30 11:36:55 -0400, Asumu Takikawa wrote:
> Sam and I discussed this some more, and we think it sounds workable and
> will go and try to add it to the Redex model and see what tests fail. We
> were concerned about one thing though: it sounds like this would modify
> the behavior of `call/cc` depending on whether or not you put a
> `dynamic-wind` in your continuation.

How about instead of using the dynamic winds to determine if the handler
is invoked, we instead invoke the handler if the prompt for the captured
continuation and its invocation sites are different? It seems like this
would still be enough for TR, but shouldn't affect dynamic wind uses
because the prompts being different should imply that all dynamic winds
handlers would be run anyway.

I think this is also fine for continuation barriers, which Eric Dobson
pointed out is a problem if it's just based on dynamic winds.

I've attached a patch that implements something like what I described,
although I'm not confident about its correctness. It works on small
examples, but there are a bunch of failing prompt tests due to another
issue I'll describe.

Consider the following interaction:

$ racket -e "(let () (define f (call-with-continuation-prompt (lambda () (call/cc (lambda (k) k))))) (f 5))"
5
$ echo $?
0

$ racket -e "(abort-current-continuation (default-continuation-prompt-tag) 5)"
$ echo $?
1

In the first example, `f` is bound to a continuation that should abort
the continuation up to the prompt (w/ default tag) and it's invoked. In
the second example, the current continuation is aborted with the same
tag.

Yet, the second results in `(exit 1)` because it's handled by an
internal error handler. This happens using `racket -e` or when using
`load`. Is this difference intentional?

Unfortunately, it also means that a `call/cc` that truly aborts and then
installs a composable continuation at the handler will also trigger an
`(exit 1)` in many Racket core tests (since they're all loaded without
installing a real prompt).

Is this a dead end or is there a better way to deal with this?

Cheers,
Asumu

Posted on the dev mailing list.