抱歉,这个简单的延续示例的计算结果为 4,但我不知道为什么:
(call/cc
(lambda (k)
(* 5 (k 4))))
Chez 计划 9.5.3
抱歉,这个简单的延续示例的计算结果为 4,但我不知道为什么:
(call/cc
(lambda (k)
(* 5 (k 4))))
Chez 计划 9.5.3
call/cc
让您获得延续传递风格的优势,而无需编写延续传递风格。例如。
(define (cars lsts)
(define (cars lsts k)
(cond ((null? lsts) (k '()))
((null? (car lsts)) '())
(else (cars (cdr lsts)
(lambda (r)
(k (cons (caar lsts) r)))))))
(cars lsts values))
;; eg
(cars '()) ; ==> ()
(cars '((1) (2) (3))) ; ==> (1 2 3)
(cars '((1) (2) ())) ; ==> ()
可以这样写:
(define (cars lsts)
(call/cc
(lambda (bail)
(define (cars lsts)
(cond ((null? lsts) '())
((null? (car lsts)) (bail '()))
(else (cons (caar lsts) (cars (cdr lsts))))))
(cars lsts))))
call/cc&
在 CPS 中看起来像这样:
(define (call/cc& proc k)
(define (exit& v ignored-k)
(k v))
(proc exit& k))
您的简单示例可以很容易地重写为继续传递样式:
(call/cc& (lambda (k& real-k)
(k& 4 (lambda (res)
(*& 5 res real-k))))
display)
因此,看着被忽略并且 4 被传递给我放置ignore-k
的延续,然后显示在 repl 中。call/cc&
display
4
我将通过使用 CPS 编写具有相同语义的代码来向您解释。
((lambda (k)
(k 4
(lambda (v)
(* 5 v))))
(lambda (result stack)
;; this continuation will drop the stack
result))
在调用延续 K 之后,您还使用剩余的堆栈调用它,但堆栈被丢弃。
如果您考虑到您将拥有的剩余堆栈:
((lambda (k)
(k 4
(lambda (v)
(* 5 v))))
(lambda (result stack)
;; this continuation will consider the stacked computation
(stack result)))
在这种情况下,结果将是 20。
但是在您的代码的语义中,通过调用延续,您丢弃了堆栈,即未完成的计算。
延续将返回传递给它的值(k 4)
,返回值也是如此4
。