(define d
(append '(a) (call/cc
(lambda (k) (k (append '(b) '(c)))))))
(define e
(append '(a) (append '(b) '(c))))
d和e之间的调用堆栈有什么区别?
答案 0 :(得分: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),它将使用continuation(abort)返回#f而不是让追加做它的事情。这个例子可以在没有call / cc的情况下编写(通过读取,如果是第一部分,但在某些情况下,继续的替代方法是完成一半你知道将要被丢弃的计算。
call / cc就像是其他语言中的goto,可用于进行异常,协作式多任务处理,迭代,++。见Matt Might's Continuations by example