Continuations

Just been reading a tutorial on continuations (Postscript - Postscript! WTF! It’s 2004!) and I think I understand now. I first read about continuations in Lshift’s discussion of their solution for NMK and again in Paul Graham’s discussion of his Lisp hacking at Viaweb.

The motivation is simple: when you write a normal program you do some stuff and then if you need user input, you ask for it. With HTTP, the user asks you for a result and you calculate it. To express web apps more easily in code, you want to be able to reverse that flow. The mechanism is also fairly simple, when you need to ask a question you have a ask_question function which saves everything, dumps a batch of HTML to the user and stops processing. When the user clicks something, you start processing again, parse the input and then pass it back up the stack. The calling function should never know that you stopped.

The bit I didn’t get is the implementation, but that’s fairly simple too (I think), you just save it somewhere. With functional programming you represent your processing as a function which is passed to a state manager of some kind, something similar to a session. On submit, you have a driver that pulls the function back out of the state table and fires it. Interestingly I believe it may be possible to implement such a strategy in languages like Java or PHP using objects. All of your processing would be encapsulated as an object (I’m already doing this in the new Hype code) and, critically, that object would contain all the state it needed at any time. A Continuable base class/interface would provide the facilities to halt and resume. I guess all internal state for each of the functions would have to be stored in class variables so that a sudden attack of halting wouldn’t mess up stuff higher up the stack. Using objects could mean that I can avoid continuation passing style, which just looks like hard work.

May have to try implementing this at some point. First I’ve got to work out how it might be used in a real-world example and get a whole lot less hazy on the implementation details. I wish I could see inside Lshift’s code for NMK, but then, they’re using a Scheme intepreter written in Java, so I guess they could attach the whole interpreter object to the session and have done with it. That would get around not having variables in the class. That and it being functional so there shouldn’t really be variables at all :-)