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 ;-)

writebacks...

Geert Bevin

Hard time
Ok Brian, why does RIFE use 'a very special cased pseudo-continuations'. It comes as close to real continuations as possible without JVM support and to the developer it works exactly as they expect: disconnected pause/resume with preservation of state and program location. The only limitation (by design) is that it only supports continuations in certain methods to allow people to use both continuation-based flow and regular flow next to each-other. The fact that the JVM doesn't support it natively requires bytecode modifications that can't be automatically applied to JDK classes, which means you risk getting holes. Afaik, Cocoon's javascript engine also besically flattens the logic to a functional style. So I don't see much difference, except that it's in pure Java without the need for any additional language or technology. Of course it would be better if the local variable stack and method call stack is fully exposed by the JVM and that every object in Java is clonable without effort, sadly this is currently not possible but we're starting to work on this ;-)

Brian McCallister

Re: Hard time
Okay, I asked for that. yeah, it is as close to a continuation as you get without JVM cotinuations ;-)

Torsten Curdt

Not just Javascript
Actually we also have a java continuations implementation in Cocoon now ...not just the javascript one :) ...but native java continuation would be way better!


wow, the JRuby guys should get a notice of this too :)

comment...

 
Name:
URL/Email: [http://... or mailto:you@wherever] (optional)
Title: (optional)
Spam Guard, translate l33t to English: (hint, it's an Australian animal, plural form)
Comments:
Save my Name and URL/Email for next time