1
(define d
  (append '(a) (call/cc
          (lambda (k) (k (append '(b) '(c)))))))

(define e
  (append '(a) (append '(b) '(c))))

d和e的调用栈有什么区别?

4

1 回答 1

0

你忘了一个:

(define d
  (append '(a) (call/cc
          (lambda (k) (append '(b) '(c))))))

您的示例和上面的示例显示了相同代码的变体。编译器会将这些简化为完全相同的表达式。

与 eval 一样,如果可以避免,则不应使用 call/cc。想象一下,您将这些列表之一作为用户的输入:

想象一下这个例子:

(define d
    (call/cc
         (lambda (abort) 
              (append    '(a) 
                         '(b) 
                         (let ((c (read))) 
                            (if (list? c) 
                                       c 
                                       (abort #f)))))))

在这里,如果您输入一个列表 d 将变为 '(ab ...),但如果您不向它提供列表(例如,您写 5),它将使用延续(中止)返回 #f 而不是让追加做它的事情。这个例子可以在没有 call/cc 的情况下编写(通过先执行 read 和 if 部分,但在某些情况下,延续的替代方法是完成一个你半路知道将被淘汰的计算。

call/cc 就像其他语言中的 goto 一样,可用于生成异常、协作多任务、迭代、++。通过示例查看Matt Might 的续集

于 2012-08-06T12:11:01.713 回答