1

抱歉,这个简单的延续示例的计算结果为 4,但我不知道为什么:

(call/cc
  (lambda (k)
    (* 5 (k 4)))) 

Chez 计划 9.5.3

4

3 回答 3

1

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&display4

于 2019-12-17T15:28:58.517 回答
1

我将通过使用 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。

但是在您的代码的语义中,通过调用延续,您丢弃了堆栈,即未完成的计算。

于 2019-12-18T11:03:02.700 回答
0

延续将返回传递给它的值(k 4),返回值也是如此4

于 2019-12-17T14:05:35.027 回答