20-CS-4003-001 Organization of Programming Languages Fall 2018
Miscellaneous Ideas

Lambda calculus, Type theory, Formal semantics, Program analysis

Prev     Next     All lectures        Code

Continuations

 ```;; an infinite recursion (define succ (lambda (n) (cons n (succ (+ n 1))))) ;; (succ 1) -> aborts on stack depth ;; a continuation is grabbed by lambda () (define succ\$ (lambda (n) (cons n (lambda () (succ\$ (+ n 1)))))) ;; the procedure is the continuation (succ\$ 1) ;; (1 . #[procedure]) ;; easy access to the continuation (define rest (cdr (succ\$ 1))) ;; #[procedure] ;; invoke the continuation (rest) ;; (2 . #[procedure]) - a new continuation ;; invoke four continuations - returns 5 (car ((cdr ((cdr ((cdr ((cdr (succ\$ 1)))))))))) ;; routine to pull out the first ;; n tokens of a stream ;; ex: (take\$ (succ\$ 1) 10) ;; creates a list (define take\$ (lambda (s n) (if (zero? n) '() (cons (car s) (take\$ ((cdr s)) (- n 1)))))) ;; routine to return the nth token in a stream ;; (take_nth\$ (succ\$ 1) 10) -> 10 (define take_nth\$ (lambda (s n) (if (= n 1) (car s) (take_nth\$ ((cdr s)) (- n 1))))) ;; factorial in non-continuation passing style ;; (fact3 -1) -> out of memory error ;; (fact3 8) -> (40320 5040 720 120 24 6 2 1) (define fact3 (lambda (p) (letrec ((fact (lambda (n acc) (if (> n p) acc (fact (+ n 1) (cons (* n (car acc)) acc)))))) (fact 2 '(1))))) ;; continuation passing style ;; (take\$ (fact3\$ 1 1) 6) -> (1 2 6 24 120 720) ;; (take_nth\$ (fact3\$ 1 1) 8) -> 40320 (define fact3\$ (lambda (n acc) (cons (* n acc) (lambda () (fact3\$ (+ n 1) (* n acc)))))) ;; put it inside a letrec (define fact4\$ (lambda (n) (letrec ((fact\$ (lambda (n acc) (cons (* n acc) (lambda () (fact\$ (+ n 1) (* n acc))))))) (take\$ (fact\$ 1 1) n)))) ``` - continuation: a construct that gives a programming language the ability to save the execution state at any point and return to that point at a later time in the program. Function succ is an infinite recursion aiming to produce a list of all positive integers if the argument is 1 - it aborts with stack overflow. Function succ\$ does the same thing except that the recursive call to succ\$ is wrapped inside a lambda. This stops execution of (succ\$ 1) with a cons pair consisting of a first token (1) plus a continuation that is the thunk (lambda () ...) which is identified by scheme as a #[procedure]. The continuation can be invoked to continue execution for one more step like this: ((cdr (succ\$ 1))) which returns (2 . #[procedure]), yet another continuation. Function take\$ invokes the continuations any number of times, assembling a list of first tokens on the way. Function take_nth\$ does the same except it returns the last element only. These are utilities that are used below. Function fact3 computes a list of consecutive factorials in reverse order. It is not written in continuation passing style. The invocation (fact3 -1) results in no output. Function fact3\$ does the same but it written in CPS. It can be coupled with take\$ or take_nth\$. It is used in a letrec in fact4\$. The invocation (fact4\$ -1) returns a value.