簡體   English   中英

let塊中call / cc的延續是什么

[英]What is the continuation of call/cc in a let block

我遇到了一個片段,該片段使用call / cc解釋了Continuations。 在下面提供的代碼段中,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 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表達式由后表達的call/cc表達。 如果我們添加(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)

輸出:

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中編寫它。 當您知道它是如何工作時,沒有太多魔力。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM