170 likes | 410 Views
Continuation Passing Style. Roadmap. Continuation Passing Style CPS and tail call CPS transformation. Continuation. Can we use functions to represent the control flow in a program? Yes , using the concept of a continuation . . Continuation.
E N D
Roadmap • Continuation Passing Style • CPS and tail call • CPS transformation
Continuation • Can we use functions to represent the control flow in a program? • Yes, using the concept of a continuation.
Continuation • Augment each procedure with an additional argument • The outer procedure “returns” no result, but pass the result to the argument • This function argument, receiving the result, will be called the continuation.
CPS Writing procedures so that theytake a continuation to which they pass on the computation result, and they return no result, is called continuation passing style (CPS)
CPS • CPS provides a programming technique for all forms of “non-local” control flow: • non-local jumps • exceptions • etc
CPS • CPS turns all non-tail calls into tail calls. • CPS also acts as a compilation technique to implement non-local control flow • Also acts as a formalization of non-local control flow in denotationalsemantics
Roadmap • Continuation Passing Style • CPS and tail call • CPS transformation
Ex1. Simple reporting fun report x = (print (Int.toString(x)); print "\n") fun plusk a b k = k ( a + b ) val _ = plusk 20 22 report
Ex2. Factorial fun fac n = if n = 0 then 1 else n * (fac (n - 1)) fun fack n = let fun fack_helper n k = case n of 0 => k 1 | _ => fack_helper (n - 1) (fn r => k (r * n)) in fack_helper n (fn x => x) end
Ex3. Length fun length xs = case xs of [] => 0 | _::xs' => 1 + length xs' fun lengthkxs k = case xs of [] => k 0 | _::xs' => lengthkxs' (fn r => k (1 + r))
Roadmap • Continuation Passing Style • CPS and tail call • CPS transformation
CPS transformation 1. Add a continuation argument to any function definition: fun f args = e fun f args k = [e]k Here we use [e]k to mean the transformation will continue in e with continuation k
CPS transformation 2. Expression with no available function callsin tail position should be passed to a continuation instead of returned return a k a
CPS transformation 3. Augment every function call in tail position by passing it the current continuation return f argsf args k
CPS transformation 4. Now, each function call not in tail position needs to be built into a new continuation, containing the old continuation and the remainder of the operation that still needs to be performed. op (f args) f args (fnr => [op r]k) [More examples see the code file]
Conclusion • Continuation Passing Style • CPS and tail call • CPS transformation