(define d
(append '(a) (call/cc
(lambda (k) (k (append '(b) '(c)))))))
(define e
(append '(a) (append '(b) '(c))))
d和e的调用栈有什么区别?
你忘了一个:
(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 的续集