Unformatted text preview:

182CS 538 Spring 2008©ContinuationsIn our Scheme implementation of*list, we’d like a way to delaydoing any multiplies until weknow no zeros appear in the list.One approach is to build acontinuation—a function thatrepresents the context in which afunction’s return value will beused:(define (*listC L con) (cond ((null? L) (con 1)) ((= 0 (car L)) 0) (else (*listC (cdr L) (lambda (n) (* n (con (car L))))) ) ))183CS 538 Spring 2008©The top-level call is(*listC L (lambda (x) x))For ordinary lists *listC expandsto a series of multiplies, just like*list did.(define (id x) x)(*listC '(1 2 3) id) ⇒(*listC '(2 3) (lambda (n) (* n (id 1))))≡(*listC '(2 3) (lambda (n) (* n 1)))⇒(*listC '(3) (lambda (n) (* n (* 2 1))))≡(*listC '(3) (lambda (n) (* n 2)))⇒(*listC () (lambda (n) (* n (* 3 2))))≡(*listC () (lambda (n) (* n 6)))⇒ (* 1 6) ⇒ 6184CS 538 Spring 2008©But for a list with a zero in it, weget a different execution path:(*listC '(1 0 3) id) ⇒(*listC '(0 3)(lambda (n) (* n (id 1))))⇒ 0No multiplies are done!185CS 538 Spring 2008©Another Example ofContinuationsLet’s redo our list multiplyexample so that if a zero is seenin the list we return a functionthat computes the product of allthe non-zero values and aparameter that is the“replacement value” for theunwanted zero value. Thefunction gives the caller a chanceto correct a probable error in theinput data.We create(*list2 L) ≡Product of all integers in L ifno zero appearselse(lambda (n) (* n product-of-all-nonzeros-in-L)186CS 538 Spring 2008©(define (*list2 L) (*listE L id))(define (*listE L con) (cond ((null? L) (con 1)) ((= 0 (car L)) (lambda(n) (* (con n) (*listE (cdr L) id)))) (else (*listE (cdr L) (lambda(m) (* m (con (car L)))))) ))187CS 538 Spring 2008©In the following, we check to seeif *list2 returns a number or afunction. If a function is returned,we call it with 1, effectivelyremoving 0 from the list(let ( (V (*list2 L)) ) (if (number? V) V (V 1) ))188CS 538 Spring 2008©For ordinary lists *list2 expandsto a series of multiplies, just like*list did.(*listE '(1 2 3) id) ⇒(*listE '(2 3) (lambda (m) (* m (id 1))))≡(*listE '(2 3) (lambda (m) (* m 1)))⇒(*listE '(3) (lambda (m) (* m (* 2 1))))≡(*listE '(3) (lambda (m) (* m 2)))⇒(*listE () (lambda (m) (* m (* 3 2))))≡(*listE () (lambda (n) (* n 6)))⇒ (* 1 6) ⇒ 6189CS 538 Spring 2008©But for a list with a zero in it, weget a different execution path:(*listE '(1 0 3) id) ⇒(*listE '(0 3) (lambda (m) (* m (id 1))))⇒(lambda (n) (* (con n) (* listE '(3) id)))≡(lambda (n) (* (* n 1)(* listE '(3) id)))≡(lambda (n) (* (* n 1) 3))This function multiplies n, thereplacement value for 0, by 1 and3, the non-zero values in the inputlist.190CS 538 Spring 2008©But note that only one zero valuein the list is handled correctly!Why?(define (*listE L con) (cond ((null? L) (con 1)) ((= 0 (car L)) (lambda(n) (* (con n)(*listE (cdr L) id)))) (else (*listE (cdr L) (lambda(m) (* m (con (car L)))))) ))191CS 538 Spring 2008©Continuations in SchemeScheme provides a built-inmechanism for creatingcontinuations. It has a long name:call-with-current-continuationThis name is often abbreviated ascall/cc(perhaps using define).call/cc takes a single function asits argument. That function alsotakes a single argument. That is,we usecall/cc as(call/cc funct) wherefunct ≡ (lambda (con) (body))call/cccalls the function that itis given with the “currentcontinuation” as the function’sargument.192CS 538 Spring 2008©Current ContinuationsWhat is the current continuation?It is itself a function of oneargument. The currentcontinuation function representsthe execution context withinwhich the call/cc appears. Theargument to the continuation is avalue to be substituted as thereturn value of call/cc in thatexecution context.For example, given(+ (fct n) 3)the current continuation for(fct n) is (lambda (x) (+ x 3)Given (* 2 (+ (fct z) 10))the current continuation for (fct z) is(lambda (m) (* 2 (+ m 10))193CS 538 Spring 2008©To use call/cc to grab acontinuation in (say) (+ (fct n) 3)we make (fct n) the body of afunction of one argument. Call thatargument return. We therefore build(lambda (return) (fct n))Then(call/cc (lambda (return) (fct n)))binds the current continuation toreturn and executes (fct n).We can ignore the currentcontinuation bound to returnand do a normal returnorwe can use return to force areturn to the calling context of thecall/cc.The call (return value) forcesvalue to be returned as the valueof call/cc in its context of call.194CS 538 Spring 2008©Example:(define (g con) (con 5))Now during evaluation no divideby zero error occurs. Rather, when(g return) is called, 5 is passedto con, which is bound to return.Therefore 5 is used as the value ofthe call to call/cc, and 50 iscomputed.(* (call/cc (lambda(return) (/ (g return) 0))) 10)return195CS 538 Spring 2008©Continuations are JustFunctionsContinuations may be saved invariables or data structures andcalled in the future to “reactive” acompleted or suspendedcomputation.(define CC ())(define (F) (let ( (v (call/cc (lambda(here) (set! CC here) 1))))(display "The ans is: ") (display v)(newline)) )This displays The ans is: 1At any time in the future, (CC 10)will display The ans is: 10196CS 538 Spring 2008©List Multiplication RevisitedWe can use call/cc toreimplement the original *list toforce an immediate return of 0(much like a throw in Java):(define (*listc L return) (cond ((null? L) 1) ((= 0 (car L)) (return 0)) (else (* (car L)(*listc (cdr L) return)))) )(define (*list L) (call/cc (lambda (return) (*listc L return)) ))A 0 in L forces a call of (return0) which makes 0 the value ofcall/cc.197CS 538 Spring 2008©Interactive Replacement ofError ValuesUsing continuations, we can alsoredo *listE so that zeroes canbe replaced interactively! Multiplezeroes (in both original andreplacement values) are correctlyhandled.(define (*list L) (let ( (V (call/cc (lambda (here) (*liste L here)))) ) (if (number? V) V (begin (display "Enter new value for 0") (newline) (newline) (V (read)) ) ) ))198CS 538 Spring 2008©(define (*liste L return) (if (null? L) 1 (let loop ((value (car L))) (if (= 0 value) (loop


View Full Document

UW-Madison COMPSCI 538 - Lecture 18 Notes

Download Lecture 18 Notes
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Lecture 18 Notes and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Lecture 18 Notes 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?