Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!lll-winken!elroy.jpl.nasa.gov!sdd.hp.com!mips!dimacs.rutgers.edu!bcm!rice!leto.rice.edu!matthias From: matthias@leto.rice.edu (Matthias Felleisen) Newsgroups: comp.lang.scheme Subject: Re: bindings captured by continuations Message-ID: <1991Apr20.033822.12436@rice.edu> Date: 20 Apr 91 03:38:22 GMT References: <1991Apr19.105244.27822@hellgate.utah.edu> Sender: news@rice.edu (News) Organization: Rice University, Houston Lines: 397 Cc: harald@hellgate.utah.scheme Bob Hieb and I developed a calculus of Scheme, very much along the lines of Church's lambda calculus, based on which we can manipulate the program text of a Scheme program to explain its results and effects. Translated into Scheme syntax and conventions, your program would evaluate as sketched below. Hope that helps -- Matthias Felleisen {Felleisen, M. and R. Hieb}. The revised report on the syntactic theories of sequential control and state. Technical Report 100, Rice University, June 1989. {\it Theor. Comput. Sci.}, 1991, to appear. A program is a sequence of defines plus an expression (or several). The define's represents the "store", the context of the leftmost-outermost redex the "continuation". { (define cont1) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (cmaker)} --> deref cmaker { (define cont1) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))} --> make "count" global (rename if necessary) { (define cont1) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 0) (begin (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))} --> deref "count" { (define cont1) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 0) (begin (if (= 0 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))} --> compare (built-in rules about =) { (define cont1) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 0) (begin (if #t (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))} --> if test for #t { (define cont1) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 0) (begin (call-with-current-continuation (lambda (cont) (set! cont1 cont))) (set! count (+ count 1)) (newline) (display count))} --> grab the continuation: the rest of the begin { (define cont1) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 0) (begin ((lambda (cont) (set! cont1 cont)) (lambda (arg) (stop ; ignore current stack (begin arg (set! count (+ count 1)) (newline) (display count))))) (set! count (+ count 1)) (newline) (display count))} --> beta-value { (define cont1) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 0) (begin (set! cont1 (lambda (arg) (stop ; ignore current stack (begin arg (set! count (+ count 1)) (newline) (display count))))) (set! count (+ count 1)) (newline) (display count))} --> store the continuation in "cont1" { (define cont1 (lambda (arg) (stop (begin arg (set! count (+ count 1)) (newline) (display count))))) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 0) (begin '**void** ; or whatever set! returns (set! count (+ count 1)) (newline) (display count))} --> bump "count" { (define cont1 (lambda (arg) (stop (begin arg (set! count (+ count 1)) (newline) (display count))))) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 1) (begin '**void** ; or whatever set! returns (newline) (display count))} --> print newline { (define cont1 (lambda (arg) (stop (begin arg (set! count (+ count 1)) (newline) (display count))))) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 1) (begin '**void** ; or whatever set! returns (display count))} |> newline; --> deref "count" { (define cont1 (lambda (arg) (stop (begin arg (set! count (+ count 1)) (newline) (display count))))) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 1) (begin (display 1))} |> newline; --> print 1 { (define cont1 (lambda (arg) (stop (begin arg (set! count (+ count 1)) (newline) (display count))))) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 1)} |> newline; 1 ;; return ;; now, continuing: { (define cont1 (lambda (arg) (stop (begin arg (set! count (+ count 1)) (newline) (display count))))) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 1) (cont1 'dummy)} --> { (define cont1 (lambda (arg) (stop (begin arg (set! count (+ count 1)) (newline) (display count))))) (define (cmaker) (let ((count 0)) (if (= count 0) (call-with-current-continuation (lambda (cont) (set! cont1 cont)))) (set! count (+ count 1)) (newline) (display count))) (define count 1) ((lambda (arg) (stop (begin arg (set! count (+ count 1)) (newline) (display count)))) 'dummy)} --> etcetera as above