[英]What is the continuation of call/cc in a let block
I came across a snippet explaining Continuations using call/cc. 我遇到了一个片段,该片段使用call / cc解释了Continuations。 In the snippet provided below, what is the continuation for the fn called by call/cc is the entire let block, or the lines below the call/cc ?
在下面提供的代码段中,call / cc调用的fn的延续是整个let块,还是call / cc之下的行? Also can someone provide an explanation on why the entire let block is not provided as the 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))
;
(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)
The continuation of the call/cc
expression consists of the expressions after the call/cc
expression. 所述的继续
call/cc
表达式由后表达的call/cc
表达。 If we add (displayln "Entering let")
we can see that invoking the continuation doesn't cause "Entering let" to be printed. 如果我们添加
(displayln "Entering let")
我们可以看到调用继续操作不会导致打印“ Entering 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)
Output: 输出:
Entering let
I am back
Leaving let
1
I am back
Leaving let
2
I am back
Leaving let
3
The implementations rewrites the whole thing into Continuation Passing Style (=CPS): 实现将整个内容重写为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)
Notice this works even without using call/cc
. 请注意,即使不使用
call/cc
此方法也可以工作。 Thats because call/cc
is just a way to get he features of CPS without having to write it in CPS. 那是因为
call/cc
只是获得CPS功能的一种方法,而不必在CPS中编写它。 There is not much magic when you know how it really works. 当您知道它是如何工作时,没有太多魔力。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.