Quiz 1: Continuations and Tail Recursion

1. Write a tail-recursive version of `factorial` in Scheme.

```;;; Compute n!
(define (factorial n)
(trfact n 1))
;;; Compute a*(n!)
(define (trfact n a)
; if n is 0, we're done, a*n! = a*0! = a*1 = a
(if (zero? n) a
; otherwise, a*n! = a*n*n-1*...*2*1 = a*n*(n-1)!
(trfact (- n 1) (* n a))))
```

2. Convert `(+ e1 e2 e3)` to continuation-passing style. You must ensure that the expressions are executed in the order e2, e3, e1.

After computing e2, we

• compute e3
• compute e1

Here is the continuation for e2.

```(lambda (E2) (+ e1 E2 e3))
```

Our expression is now

```((lambda (E2) (+ e1 E2 e3))
e2)
```

What is the continuation for e3?

• compute e1

Which may be expresed as

```(lambda (E3) (+ e1 E2 E3))
```

Plugging in, our expression is now

```((lambda (E2)
((lambda (E3) (+ e1 E2 E3))
e3))
e2)
```

Finally, we want to say evaluate e1 and add the three results. The continuation is

```(lambda (E1) (+ E1 E2 E3))
```

Putting it all together, we get

```((lambda (E2)
((lambda (E3)
((lambda (E1)
(+ E1 E2 E3))
e2))
e3))
e2)
```

Now, let's say that there were alternate versions of e1, e2, and e3 that took continuations as arguments. We'll call them e1-cps, e2-cps, e3-cps.

Switching stuff around to use e2-cps, we get

```(e2-cps ((lambda (E2)
((lambda (E3)
((lambda (E1)
(+ E1 E2 E3))
e1))
e3))))
```

Switching stuff around to use e3-cps, we get

```(e2-cps ((lambda (E2)
(e3-cps ((lambda (E3)
((lambda (E1)
(+ E1 E2 E3))
e1)))))))
```

Finally, we switch stuff around to use e1-cps.

```(e2-cps ((lambda (E2)
(e3-cps ((lambda (E3)
(e1-cps ((lambda (E1)
(+ E1 E2 E3)))))))))))
```

Or, in English,

• Evaluate e2, call the result E2
• Evaluate e3, call the result E3
• Evaluate e1, call the result E1
• Sum E1, E2, and E3.

We now have a precise order.

Disclaimer Often, these pages were created ``on the fly'' with little, if any, proofreading. Any or all of the information on the pages may be incorrect. Please contact me if you notice errors.