Created
December 3, 2017 13:15
-
-
Save jooyunghan/0dab021c293b0d14b7039077c8b8594c to your computer and use it in GitHub Desktop.
One-shot continuation using symmetric coroutines
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const coro = require('symcoro'); | |
| const {create, transfer} = coro; | |
| // Figure 4. Implementing one-shot continuations with symmetric coroutines | |
| // http://www.inf.puc-rio.br/~roberto/docs/MCC15-04.pdf | |
| function* call1cc(f) { | |
| // save the continuation "creator" | |
| let currentCoro = coro.current; | |
| // invoking the continuation transfers control | |
| // back to its creator | |
| function* cont(val) { | |
| if (currentCoro === null) { | |
| throw new Error('one shot continuation called twice'); | |
| } | |
| yield* coro.transfer(currentCoro, val); | |
| } | |
| const val = yield* coro.transfer( | |
| coro.create(function*() { | |
| const v = yield* f(cont); | |
| yield* cont(v); | |
| }) | |
| ); | |
| // when control is transfered back, the continuation | |
| // was "shot" and must be invalidated | |
| currentCoro = null; | |
| // the value passed to the continuation | |
| // is the return value of call1/cc | |
| return val; | |
| } | |
| coro.run(function*() { | |
| return yield* call1cc(function*(cont) { | |
| yield* transfer(create(function* nested() { | |
| yield* transfer(create(function* nestedAgain() { | |
| yield* cont(42); | |
| })); | |
| })); | |
| }); | |
| }, console.log); //42 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment