CSC302 2007S, Class 17: Continuation Basics Admin: * Penalties awarded to EOno' (2 points), GG (1 point), LZ * I'll reserve some time at the start of class to discuss the upcoming homework. * EC: G-Tones Concert on Friday at 7:30 in the Bucksbaum rotunda. * EC: Henry Walker speaks on Google®'s PageRank® algorithm Thursday at noon. * EC: Jackie Brown's Convocation. Overview: * Basics of Continuations. * Two examples. * Some Applications of Continuations. * Continaution-Passing Style. /Homework 5/ * Goal: Generic Hash Table * Key types are generic * Value types are generic * Hash function is generic * Perhaps equality function, too * Goal 1: Functions as parameters in C * Goal 2: Serious genericity in C In your code * Use constants for types, and #define them elsewhere struct hashtable_entry { KEYTYPE key; VALUETYPE value; } ... #define KEYTYPE char * #define VALUETYPE char * * Instead of giving functions (and your types) names, give them partial names and apply the PREFIX macro to those names. PREFIX(put)(KEYTYPE key, VALUETYPE value) { ... } Make PREFIX a macro #define PREFIX(thing) ss_ ## thing * For a specific implementation, #define KEYTYPE ____ #define VALUETYPE _____ #define PREFIX(thing) ___ ## thing * See Examples/generic.c and Examples/stringstring.c and Examples/intstring.c /Continuations: Some Basics/ * A continuation is "a function representing the future of a computation" * What computing we have to do next "at this point in the program" * This "what happens next" is implicit in every languageq * Design goal of Scheme and Lisp: Make things explicit, as values * Functions can be values * Code can be a value * Continuations: Computation can be a value * Implicitly, a continuation is * The call stack * The code * The symbol table * Let's consider a silly computation (* 3 (+ (/ 4 x) a)) * The continuation is (/ 4 x) is "add a, then multiply by 3" (lambda (tmp) (* 3 (+ tmp a))) * In Scheme, you can grab the continuation at any point of the code (call-with-current-continuation (lambda (cont) ...)) (call/cc (lambda (cont) ...)) (let/cc cont ...) An Example (define foo null) (define a 5) (define x 4) (* 3 (+ (let/cc cont (set! foo cont) (/ 4 x)) a)) > foo # > (foo 1) 18 > (foo 2) 21 * A Subtlety (+ 5 (foo 2)) * Ignores the plus five * Why? Calling a continuation *replaces the call stack at that point* How do programmers use continuations? Two examples (define product0 (lambda (lst) (if (null? lst) 1 (multiply (car lst) (product0 (cdr lst)))))) (define product1 (lambda (lst) (cond ((null? lst) 1) ((zero? (car lst)) 0) (else (multiply (car lst) (product1 (cdr lst))))))) (define product (lambda (lst) (let/cc escape (letrec ((kernel (lambda (lst) (cond ((null? lst) 1) ((zero? (car lst)) (escape 0)) (else (multiply (car lst) (kernel (cdr lst)))))))) (kernel lst))))) (define multiply (lambda (x y) (let ((result (* x y))) (display x) (display "*") (display y) (display "=") (display result) (newline) result))) (define silly (lambda (a x def) (times 3 (plus (divide 4 x) a)))) (define times (lambda (val1 val2) (let ((result1 val1) (result2 val2)) (cond ((not (number? val1)) val1) ((not (number? val2)) val2) (else (* val1 val2)))))) Continuations permit exceptions!