Introduction Defining A Motivating Example Continuations Further Reading Introduction Defining Continuations A Motivating Example Continuations Further Reading

Objectives You should be able to...

Continuations It is possible to use functions to represent the of a program. This technique is called passing style. After today’s lecture, Dr. Mattox Beckman you should be able to

University of Illinois at Urbana-Champaign I explain what CPS is, Department of I give an example of a programming technique using CPS, and

I transform a simple function from direct style to CPS.

Introduction Defining Continuations A Motivating Example Continuations Further Reading Introduction Defining Continuations A Motivating Example Continuations Further Reading

Direct Style The Continuation

Example Code result = inc (double (half 10)) inc x = x + 1 I We can ‘punch out’ a subexpression to create an expression with a double x = x * 2 ‘hole’ in it. half x = x `div` 2 result = inc (double [[]]) result = inc (double (half 10)) I This is called a context. After half 10 runs, its result will be put into this context.

I Consider the function call above. What is happening? I We can call this context a continuation. Introduction Defining Continuations A Motivating Example Continuations Further Reading Introduction Defining Continuations A Motivating Example Continuations Further Reading

Making Continuations Explicit Properties of CPS

I A function is in Direct Style when it returns its result back to the I We can make continuations explicit in our code. caller. cont = \ v -> inc (double v) I A Tail Call occurs when a function returns the result of another I Instead of returning, a function can take a continuation argument. function call without processing it first. I This is what is used in accumulator . Using a Continuation I A function is in Continuation Passing Style when it passes its result half x k = k (x `div` 2) to another function. result = half 10 cont I Instead of returning the result to the caller, we pass it forward to another function. I Convince yourself that this does the same thing as the original code. I Functions in CPS “never return”.

I Lets see some more examples.

Introduction Defining Continuations A Motivating Example Continuations Further Reading Introduction Defining Continuations A Motivating Example Continuations Further Reading

Comparisons CPS and Imperative style

CPS Direct Style I CPS look like imperative style if you do it right. inc x k = k (x + 1) inc x = x + 1 double x k = k (x * 2) CPS Imperative Style double x = x * 2 half x k = k (x `div` 2) half x = x `div` 2 id x = x result = half 10 (\v1 -> v1 := half 10 result = half 10 (\v1 -> double v1 (\v2 -> v2 := double v1 result = inc (double (half 10)) double v1 (\v2 -> inc v2 id)) result := inc v2 inc v2 id)) Introduction Defining Continuations A Motivating Example Continuations Further Reading Introduction Defining Continuations A Motivating Example Continuations Further Reading

The GCD Program GCD of a list

gcdstar [] = 0 gcdstar (x:xs) = gcd x (gcdstar xx) gcd a b | b == 0 = a | a < b = gcd b a > gcdstar [44, 12, 80, 6] | otherwise = gcd b (a `mod` b) 2 > gcdstar [44, 12] gcd 44 12 gcd 12 8 gcd 8 4 gcd 4 0 4 ⇒ ⇒ ⇒ ⇒ 4 I The running time of this function is roughly (lg a). O I Question: What will happen if there is a 1 near the beginning of the sequence?

I We can use a continuation to handle this case.

Introduction Defining Continuations A Motivating Example Continuations Further Reading Introduction Defining Continuations A Motivating Example Continuations Further Reading

Definition of a Continuation Continuation Solution

I A continuation is a function into which is passed the result of the gcdstar xx k = aux xx k current function’s computation. where aux [] newk = newk 0 aux (1:xs) newk = k 1 > report x = x aux (x:xs) newk = aux xs (\res -> newk (gcd x res)) > plus a b k = k (a + b) > plus 20 33 report > gcdstar [44, 12, 80, 6] report 53 2 > plus 20 30 (\x-> plus 5 x report) > gcdstar [44, 12, 1, 80, 6] report 55 1 Introduction Defining Continuations A Motivating Example Continuations Further Reading Introduction Defining Continuations A Motivating Example Continuations Further Reading

The CPS Transform, Simple Expressions The CPS Transform, Function Calls

Top Level Declaraion To convert a declaration, add a continuation argument to it and then convert the body. Function Call on Simple Argument To a function call in tail position (where arg is simple), pass the current continuation.

C[[f arg = e)]] f arg k = [[e]]k ⇒ C[[f arg]]k f arg k Simple Expressions A simple expression in tail position should be passed ⇒ to a continuation instead of returned. Function Call on Non-simple Argument If arg is not simple, we need to convert it first. C[[a]]k k a ⇒ C[[f arg]]k C[[arg]] , where v is fresh. ⇒ (λv.f v k) I “Simple” = “No available function calls.”

Introduction Defining Continuations A Motivating Example Continuations Further Reading Introduction Defining Continuations A Motivating Example Continuations Further Reading

Example The CPS Transform, Operators

Operator with Two Simple Arguments If both arguments are simple, then the whole thing is simple.

foo 0 = 0 C[[e + e ]]k k(e + e ) 1 2 ⇒ 1 2 foo n | n < 0 = foo n Operator with One Simple Argument If e is simple, we transform e . | otherwise = inc (foo n) 2 1

foo 0 k = k 0 C[[e1 + e2]]k C[[e1]](λv >k(v+e2))where v is fresh. foo n k | n < 0 = foo n k ⇒ − | otherwise = foo n (\v -> inc v k) Operator with No Simple Arguments If both need to be transformed...

C e e C e where v and v are fresh. [[ 1+ 2]]k [[ 1]](λv1 >C[[e2]]λv >k(v +v )) 1 2 ⇒ − 2− 1 2 Notice that we need to nest the continuations! Introduction Defining Continuations A Motivating Example Continuations Further Reading Introduction Defining Continuations A Motivating Example Continuations Further Reading

Examples Other Topics

foo a b = a + b bar a b = inc a + b baz a b = a + inc b I Continuations can simulate exceptions. quux a b = inc a + inc b I They can also simulate cooperative multitasking. I These are called co-routintes.

foo a b k = k a + b I Some advanced routines are also available: call/cc, shift, reset. bar a b k = inc a (\v -> k (v + b)) baz a b k = inc b (\v -> k (a + v)) quux a b k = inc a (\v1 -> inc b (\v2 -> k (v1 + v2)))