2016-09-14 84 views
1

我遇到了一個使用call/cc解釋Continuations的片段。在下面提供的片段中,call/cc調用的fn的延續是整個let塊還是調用/ cc下面的行?也有人可以提供一個解釋,爲什麼不提供整個let塊作爲延續?什麼是呼叫/ cc在一個區塊的延續

#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) 

回答

1

call/cc表達的繼續由call/cc表達後的表達式 。 如果添加(displayln "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 
+0

我從例子中推斷出來。在'(+ 1(call/cc(lambda(k)(k 2)))3)'中,延續是'(fn [v](+ 1 v 2))'。但在'(let(bindings)'的情況下,延續是調用/ cc後語句的狀態,我想(我認爲我是對的)let(bindings)可以被重寫爲lambda()其中的代碼在一個do塊中,所以繼續是有效的調用/ cc之後的語句集合 – draklor40

1

的實現重寫了整個事情變成延續傳遞風格(= 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中編寫它。當你知道它是如何工作的時候,沒有太多的魔力。