Safari Books Online is a digital library providing on-demand subscription access to thousands of learning resources.
| 1. | In the example of Section 22.1, “Capturing and Invoking a Continuation,” on page 320, suppose there is no file myfile.txt. Now set filename to another nonexistent file and call cont. What happens? Set filename to a file that exists and call cont again. What happens? Call cont one more time. What happens? First, think through the control flow, then run a program to verify. |
| 2. | Improve the example of Section 22.1, “Capturing and Invoking a Continuation,” on page 320 so that the continuation function passes the name of the next file to try as a parameter. |
| 3. | Make the example in Section 22.7, “Turning a Recursive Visit into an Iteration,” on page 326 into an iterator. The constructor of the iterator should contain the reset, and the next method should invoke the continuation. |
| 4. | The example in Section 22.8, “Undoing Inversion of Control,” on page 329 is a bit unsightly—the application programmer sees the reset statement. Move reset from the run method to the button listener. Is the application programmer now blissfully unaware of continuations? |
| 5. | Consider this sample program that uses a continuation to turn an iteration into an iterator:
object Main extends App {
var cont: Unit => String = null
val a = "Mary was a little lamb".split(" ")
reset {
var i = 0
while (i < a.length) {
shift {
k: (Unit => String) => {
cont = k
a(i)
}
}
i += 1
}
""
}
println(cont())
println(cont())
}Compile with the -Xprint:selectivecps flag and look at the generated code. How is the while statement treated when transformed to CPS? |