Eric Lippert of Fabulous Adventures In Coding has posted a series on CPS tranformation and different control flow abstractions. Good stuff — recommended reading for translating the crazy stuff I talk about into ‘normal’ code.
- Continuation Passing Style Revisited, Part One.
- Continuation Passing Style Revisited Part Two: Handwaving about control flow.
- Continuation Passing Style Revisited Part Three: Musings about coroutines.
- Continuation Passing Style Revisited Part Four: Turning yourself inside out.
- Continuation Passing Style Revisited Part Five: CPS and Asynchrony.
I bet part 2 will cover exception handling. That, or call/cc, then EH in part 3. We’ll see 🙂
Update (10/22): Yay, I was right, EH is up next. He also writes “Next time: handwaving about coroutines”. I’m sure call/cc will be in part 3.
Update (10/25): Part 3 is up — skips call/cc (makes sense, as Eric it talking about writing CPS explicitly) moving straight to one application of CPS: coroutines. Ominiously ends with “Next time: if Continuation Passing Style is so awesome then why don’t we all use this technique every day?” Presumably he will be talking about the specific implementation technique he’s chosen, as various runtime environments (usually Scheme implementations) *do* use CPS for compilation all the time, and a few do so with no ill effect.
Update (10/27): Part 4 and 5 are up. Part 4 notes that CPS is generally *hard* to understand for most folks, but that CPS is ultimately general purpose, making for quick implementation of a wide variety of programming language control flow constructs.
Part 5 further talks about the explicit use of CPS in designing asynchronous programming APIs. I’m somewhat disappointed that Eric skips over the CPS to model for loops, instead resorting to a state machine like the C# compiler uses when compiling iterator syntax. It’s a fine implementation technique, but it seems like a missed opportunity to me, and it would have avoided the “definite assignment problem” he mentioned. And lastly, while the invocation of the continuation was straightforward in CPS, a lot of synchronization work has been glossed over in ‘SetContinuation’ — the continuation may not always be ready by the time that ‘AsyncFetch’ goes to invoke it. This seems unnecessarily wasteful, as the caller always knows the continuation they’re about to set — the caller code is simplified only by reordering, at the expense of runtime cost and added complexity in AsyncFetch.
I think the switch to use ‘SetContinuation/GetResults’ is done too early. It makes it easier to connect his example to .Net’s Task Parallel Library, but now there isn’t a single example in direct CPS style that demonstrates asynchrony.
I’m only so critical of Part 5 as I think Eric Lippert has done quite well in the rest of this series. To be balanced, many programmers will find the state machine model easier to read. As a CPS topic, I find Part 5 lacking; It shines as an explaination of asynchrony in .Net. It a very good piece, but is an ugly duckling in a CPS series.
Again, I appreciate his work here. Please take the time to give this series a read.