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
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4