Scheme let块中call/cc的延续是什么
我遇到了一个片段,解释了如何使用call/cc进行延续。在下面提供的代码片段中,call/cc调用的fn的延续是整个let块,还是call/cc下面的行?还有人能解释为什么整个let块不作为延续提供吗Scheme let块中call/cc的延续是什么,scheme,racket,continuations,callcc,Scheme,Racket,Continuations,Callcc,我遇到了一个片段,解释了如何使用call/cc进行延续。在下面提供的代码片段中,call/cc调用的fn的延续是整个let块,还是call/cc下面的行?还有人能解释为什么整个let块不作为延续提供吗 #lang racket (define resume-test-3 #f) (define test-3 (lambda () ; the let defines a variable i local to the lambda, and ; sets its value to
#lang racket
(define resume-test-3 #f)
(define test-3 (lambda ()
; the let defines a variable i local to the lambda, and
; sets its value to 0
(let ((i 0))
;
(call/cc (lambda (k) (set! resume-test-3 k)))
;
; The next time the-continuation is called, we start here.
(displayln "I am back ")
(set! i (+ i 1))
; and return the value i
i
)
))
(test-3)
(resume-test-3)
(resume-test-3)
call/cc表达式的继续部分包括
调用/cc表达式后的表达式的。
如果我们添加displayln,我们可以看到
调用continuation不会导致输入let
待打印
#lang racket
(define resume-test-3 #f)
(define test-3 (lambda ()
; the let defines a variable i local to the lambda, and
; sets its value to 0
(let ((i 0))
(displayln "Entering let")
;
(call/cc (lambda (k) (set! resume-test-3 k)))
;
; The next time the-continuation is called, we start here.
(displayln "I am back ")
(set! i (+ i 1))
; and return the value i
(displayln "Leaving let")
i)))
(test-3)
(resume-test-3)
(resume-test-3)
输出:
Entering let
I am back
Leaving let
1
I am back
Leaving let
2
I am back
Leaving let
3
这些实现将整个过程重写为Continuation Passing Style=CPS:
(define resume-test-3-cps #f)
(define test-3-cps
(lambda (k)
((lambda (kl i) ; this is the "let"
((lambda (tk1) (tk1 (set! resume-test-3-cps tk1)))
(lambda (not-used)
((lambda (tk2) (tk2 (displayln "I am back ")))
(lambda (not-used)
((lambda (tk3) (tk3 (set! i (+ i 1))))
(lambda (not-used)
((lambda (tk4) (tk4 (displayln "Leaving let")))
(lambda (not-used)
((lambda (tk5) (tk5 i))
kl))))))))))
k 0))) ; variables to "let"
;; top level have barriers, don't know how to simulate them
;; doing full CPS here will make an infinite loop
(test-3-cps values)
(resume-test-3-cps values)
(resume-test-3-cps values)
请注意,即使不使用call/cc,这也可以工作。这是因为call/cc只是一种获取CPS特性的方法,而无需在CPS中编写。当你知道它是如何工作的时候,就没有什么魔力了。我从这个例子中推断出了这一点。在+1调用/cc lambda k k 2 3中,延续是fn[v]+1 v 2。但是在let绑定的情况下,continuation是call/cc之后语句的状态。我想我是对的,让绑定可以重写为lambda,代码在do块中,因此continuation实际上是call/cc之后的语句集