What are Scala continuations and why use them?

My blog does explain what reset and shift do, so you may want to read that again.

Another good source, which I also point in my blog, is the Wikipedia entry on continuation passing style. That one is, by far, the most clear on the subject, though it does not use Scala syntax, and the continuation is explicitly passed.

The paper on delimited continuations, which I link to in my blog but seems to have become broken, gives many examples of usage.

But I think the best example of the concept of delimited continuations is Scala Swarm. In it, the library stops the execution of your code at one point, and the remaining computation becomes the continuation. The library then does something -- in this case, transferring the computation to another host, and returns the result (the value of the variable which was accessed) to the computation that was stopped.

Now, you don't understand even the simple example on the Scala page, so do read my blog. In it I'm only concerned with explaining these basics, of why the result is 8.


I found the existing explanations to be less effective at explaining the concept than I would hope. I hope this one is clear (and correct.) I have not used continuations yet.

When a continuation function cf is called:

  1. Execution skips over the rest of the shift block and begins again at the end of it
    • the parameter passed to cf is what the shift block "evaluates" to as execution continues. this can be different for every call to cf
  2. Execution continues until the end of the reset block (or until a call to reset if there is no block)
    • the result of the reset block (or the parameter to reset() if there is no block) is what cf returns
  3. Execution continues after cf until the end of the shift block
  4. Execution skips until the end of the reset block (or a call to reset?)

So in this example, follow the letters from A to Z

reset {
  // A
  shift { cf: (Int=>Int) =>
    // B
    val eleven = cf(10)
    // E
    println(eleven)
    val oneHundredOne = cf(100)
    // H
    println(oneHundredOne)
    oneHundredOne
  }
  // C execution continues here with the 10 as the context
  // F execution continues here with 100
  + 1
  // D 10.+(1) has been executed - 11 is returned from cf which gets assigned to eleven
  // G 100.+(1) has been executed and 101 is returned and assigned to oneHundredOne
}
// I

This prints:

11
101