Hello all, I am currently shaving a yak[0], trying to integrate nonlocal exits into the VM. That's `catch', `throw', and all that. I have also been wanting to integrate delimited continuations into Guile; that's a bigger topic. Anyway it turns out that one can implement catch and throw using delimited continuations. Flatt et al's paper at ICFP 07 [1] shows how.
Sitaram 93 shows why you want delimited continuations [2]. Felleisen 88 is the first appearance of delimited continuations that I'm aware of, though I think it's behind a paywall; Sitaram and Felleisen 90 seems to be an adequate substitute [3]. Dybvig et al 07 is a great summary of the relationship between the various delimited continuation operators [4]. [0] http://projects.csail.mit.edu/gsb/old-archive/gsb-archive/gsb2000-02-11.html [1] http://www.cs.utah.edu/plt/publications/icfp07-fyff.pdf [2] http://www.ccs.neu.edu/scheme/pubs/pldi93-sitaram.pdf [3] http://www.ccis.northeastern.edu/scheme/pubs/lasc1990-sf.pdf [4] http://www.cs.indiana.edu/~dyb/pubs/monadicDC.pdf So, the deal. The deal is that Flatt shows very clearly and elegantly how to implement catch and throw using prompt, abort, and dynamic binding. (Actually he uses the % flavor of prompt; and abort is like Sitaram's control afaict. See Sitaram 93.) The dynamic binding is for the current exception handler (corresponding to catch) and for the current "abort handler", which is like a pre-unwind handler. The problem: Well, you might want to set some exception handlers, and then spawn a bunch of threads all with those handlers. But if a pre-unwind handler throws an exception, that exception shouldn't be handled by itself, or you get an infinite loop. Basically you need a bit to say whether a given handler is running in a given thread or not -- a fluid. But you can't / shouldn't make a new fluid every time you enter a `catch', because currently fluids are never garbage collected! We really need to fix this. I think it's a 1.9 regression. To do so effectively, I think you'd need to make fluid objects store their values directly, so that the GC doesn't have to go through hoops to know that they're collectable. Ideally they would get their values via pthread_getspecific; but that would defeat some bits of ours about "dynamic states" (not a very useful concept IMO), and the GC would need help. Actually it would be nice if libgc supported thread-local allocations. (Does it?) Anyway, some disconnected thoughts here. I could have simply implemented catch and throw using what we have now, but I think it's a great opportunity to see if we can do delimited continations. There's some half-complete prompt support in master. I thought I'd get to the rest sooner, but it seems that it will take another couple weeks. I haven't been able to have good hacktime over the last week or two, so things are going slower than they usually do. Also, getting to understand delimited continuations was a bit paralyzing. Regarding the release... I have no thoughts. Perhaps I should prepare the NEWS, and we get a release out the door this week, then the next one will have catch/throw nicely integrated, and at that point I'll be mostly happy for 2.0. Thoughts? Cheers, Andy -- http://wingolog.org/