** Direct semantic Problems ** Continuations *** flavors of continuations available in semantics **** normal: continuation for code following a statement (etc.) **** exceptional: any other continuation (e.g., abort). *** uses in programming **** return multiple values --------------- (define (qr n d cont err) ; if d = 0, then call err with d as an argument, ; otherwise call cont with the quotient of n by d and the remainder (if (zero? d) (err d) (cont (quotient n d) (remainder n d)))) (qr 16 3 (lambda (q r) (+ q r)) (lambda (d) (write "oops"))) ;Value: 6 --------------- **** exception handling --------------- (define (first-negative lst do-if-none) ; effect: if there are no negative numbers in lst, call do-if-none, ; otherwise return the first negative number in lst (cond ((null? lst) (do-if-none)) ((negative? (car lst)) (car lst)) (else (first-negative (cdr lst) do-if-none)))) -------------- *** Contexts: formalizing "the rest of the program" (S&F, section 16.1) **** a "reduced form" for contexts --------------- (let ((n 1)) (begin (if (zero? n) (writeln (+ 3 (* 4 (+ 5 6)))) (writeln (* (+ (* 3 4) 5) 2))) n)) ; context of (* 3 4) is (lambda ( _ ) (begin (writeln (* (+ _ 5) 2)) n)) --------------- **** contexts of hidden expressions --------------- (define tester (lambda (n) (begin (if (zero? n) (writeln (+ 3 (* 4 (+ 5 6)))) (writeln (* (+ (* 3 4) 5) 2))) n))) ; context of (* 3 4) in (* 10 (tester 1)) is (lambda ( _ ) (* 10 (begin (writeln (* (+ _ 5) 2)) n))) ---------------- **** contexts in recursive procedures --------------- (define map-add1 (lambda (ls) (if (null? ls) (cons (+ 3 (* 4 5)) '()) (cons (add1 (car ls)) (map-add1 (cdr ls)))))) ; context of (* 4 5) in (cons 0 (map-add1 '(1 3 5))) (lambda ( _ ) (cons 0 (cons 2 (cons 4 (cons 6 (cons (+ 3 _) '())))))) --------------- *** escape procedures ------------- (define escape-* (escaper *)) (+ (escape-* 5 2) 3) ;Value: 10 (+ ((escaper (lambda (x) (- (* x 3) 7))) 5) 4) ;Value: 8 (/ (+ ((escaper (lambda (x) (- (* x 3) 7))) 5) 4) 2) ;Value: 8 ------------- *** in Scheme: call-with-current-continuation, call/cc ---------------- (define call/cc call-with-current-continuation) (call/cc receiver) = (receiver continuation) where continuation = (escaper c) and c = context of (call/cc receiver) in some expr E ---------------- --------------- (define r (lambda (cont) 6)) (+ 3 (* 4 (call/cc r))) ; = (+ 3 (* 4 (r (escaper (lambda (_) (+ 3 (* 4 _))))))) ;Value: 27 (call/cc (lambda (err-value) (qr 16 3 (lambda (q r) (+ q r)) err-value))) ;Value: 6 (call/cc (lambda (err-value) (qr 16 0 (lambda (q r) (+ q r)) err-value))) ;Value: 0 (define (first-negative lst do-if-none) (call/cc (lambda (exit) (for-each (lambda (x) (if (negative? x) (exit x))) lst) (do-if-none lst)))) (first-negative '(1 2 -3 4 5) (lambda (x) (write "oops"))) ;Value: -3 (first-negative '(1 2 3) (lambda (x) (write "oops"))) ; writes "oops" ;No value --------------- ** Standard semantics *** use continuations for control and data flow *** standard signatures for valuation functions *** Example: Standard semantics of FL! * Non-local exits ** call-with-current-continuation ** block and exit constructs (see control handout, second part) ** goto (Schmidt 9.5) *** keep command continuations for labels in environment. *** mutual recursion resolved by fixpoint to construct environment * Iteration constructs ** indefinite iteration ** definite iteration *** for loop in Pascal, map and for-each in Scheme *** generalized iteration over abstract types (e.g., sets) *** streams (or generators) **** Streams in Scheme: **** efficiency from lazy evaluation (vs. enumeration) * Final thoughts