
Tim Peters writes:
[Sam]
Continuations are more powerful than coroutines, though I admit they're a bit esoteric.
"More powerful" is a tedious argument you should always avoid <wink>.
More powerful in the sense that you can use continuations to build lots of different control structures (coroutines, backtracking, exceptions), but not vice versa. Kinda like a better tool for blowing one's own foot off. 8^)
Suppose the driver were in a script instead:
thing(5) # line 1 print repr(saved) # line 2 saved.throw(0) # line 3 saved.throw(0) # line 4
Then the continuation would (eventually) "return to" the "print repr(saved)" and we'd get an infinite output tail [...]
and never reach line 4. Right? That's the part that Guido hates <wink>.
Yes... the continuation object so far isn't very usable. It needs a driver of some kind around it. In the Scheme world, there are two common ways of using continuations - let/cc and call/cc. [call/cc is what is in the standard, it's official name is call-with-current-continuation] let/cc stores the continuation in a variable binding, while introducing a new scope. It requires a change to the underlying language: (+ 1 (let/cc escape (...) (escape 34))) => 35 'escape' is a function that when called will 'resume' with whatever follows the let/cc clause. In this case it would continue with the addition... call/cc is a little trickier, but doesn't require any change to the language... instead of making a new binding directly, you pass in a function that will receive the binding: (+ 1 (call/cc (lambda (escape) (...) (escape 34)))) => 35 In words, it's much more frightening: "call/cc is a function, that when called with a function as an argument, will pass that function an argument that is a new function, which when called with a value will resume the computation with that value as the result of the entire expression" Phew. In Python, an example might look like this: SAVED = None def save_continuation (k): global SAVED SAVED = k def thing(): [...] value = callcc (lambda k: save_continuation(k)) # or more succinctly: def thing(): [...] value = callcc (save_continuation) In order to do useful work like passing values back and forth between coroutines, we have to have some way of returning a value from the continuation when it is reinvoked. I should emphasize that most folks will never see call/cc 'in the raw', it will usually have some nice wrapper around to implement whatever construct is needed. -Sam