Brian's Waste of Time

Thu, 15 Jul 2004

Native Java Continuations

Torsten let the cat out of the bag. After James managed to extract an admission that the JVM could very easily support continuations from one of the HotSpot engineers at GroovyOne, a few people have been very hungry to expose them in the Java language.

For those not familiar with continuations, I'll quote Paul Graham's On Lisp

A continuation is a program frozen in action: a single functional object containing the state of a computation. When the object is evaluated, the stored computation is restarted where it left off. In solving certain types of problems it can be a great help to be able to save the state of a program and restart it later. In multiprocessing, for example, a continuation conveniently represents a suspended process. In nondeterministic search programs, a continuation can represent a node in the search tree.

This somewhat abstract idea has a lot of implications. This past year the idea of using continuations in web applications started to get more general acceptance and see more mainstream usage via Cocoon and RIFE but both of these cheat -- Cocoon uses a special Javascript interpreter, and RIFE uses very special cased pseudo-continuations (Geert is going to give me a hard time for saying that ;-).

Aside from web application usage, the J2EE space can make great use of them in asynchronous processes -- a workflow engine where the workflow is modeled directly in java as a procedure:

public void handleMooseAttack(Moose m, Victim v) {
    hospital.getAmbulance().transport(v);
    ranger.scold(m);
    
    v.fillOutForms(insurance.getForms());
    v.fillOutMoreForms(insurance.getOtherForms());
    for (Iterator i = insurance.getAllForms().iterator(); i.hasNext();) {
        v.fillOutYetAnotherForm((Form)i.next());
    }
    
    v.sue(insurance);
    v.sue(ranger);
    v.sue(mcdonalds);
}

This whole process may take ten years to complete, but the state of the process can be stored, migrated, etc directly instead of modeling it as a finite state machine with transitions etc.

Finally, other absurdly cool uses include "this process must not die ever" processes which can be capture, migrated to the failover server, and kept waiting until the main server dies -- then th full stack, state, everything brought right back via invoking the continuation.

That is just continuations in the large, and all of these things can be done without continuations in the JVM, they just get more convenient when you do have them. In the small is where the ideas really shine -- coroutines, generators, certain types of graph traversals, error recovery (in languages which support continuations you get java's try/catch being a trivial thing to implement, and you get other niceties like "try ... catch { retry two times; fail } finally ... end".

I know the people thus far involved want to see fully serializable and migratable continuations (scheme) rather than thread-bound continuations (ruby), which is where the really big asynchronous options will come from =) Exciting exciting.

So, if you are a continuations expert, FP weenie, or doing work that this would apply to, drop by our wiki, kindly provided by Codehaus or mailing list ( dev@continuation.codehaus.org (dev-subscribe@continuation.codehaus.org to subscribe)). We figure we have a good shot at getting it in -- after all Guy Steele works for Sun, and specifically works on Java internals ;-)

4 writebacks [/src/java] permanent link