call / cc是否以这种方式模拟goto?

时间:2015-02-12 22:05:00

标签: scheme lisp continuations callcc

Lisp in Small Pieces 一书中,有以下示例代码,用于演示call/cc可以模拟goto。

(define (fact n)
   (let ((r 1) (k 'void))
      (call/cc (lambda (c) (set! k c) 'void))
      (set! r (* r n))
      (set! n (- n 1))
      (if (= n 1) r (k 'recurse))))

但是,我不确定我是否误解了某些内容,但我看不出这是call/cc模拟goto的方式。在最后一行应用k时,已恢复的续约内容包含原始续集的rn,其值由两个{更改} {1}}应用程序。所以整个循环永远不会终止。

这个例子中的书是错的吗?或者我错过了什么?

1 个答案:

答案 0 :(得分:1)

  

恢复的延续具有原始的r和n   延续,其值不会被两组改变!   应用

都能跟得上;那是重要的一部分;值的更改可见。他们没有重置。我不确定这个问题是否应该被认为是重复的,但是这也出现在call-with-current-continuation - state saving concept中,提问者注意到了(查看整个上下文的问题):

  

接下来调用3次会产生0,1和'完成。这意味着当状态使用生成器给出的函数k时它没有   恢复程序的状态。

您可以通过在保存延续后打印r和n的值来非常简单地测试它。您将看到更新的值存在。例如:

(define (fact n)
  (let ((r 1) (k 'void))
    (call-with-current-continuation (lambda (c) (set! k c) 'void))
    (display "r: ") (display r) (newline)
    (display "n: ") (display n) (newline)
    (set! r (* r n))
    (set! n (- n 1))
    (if (= n 1) r (k 'recurse))))

> (fact 6)
r: 1
n: 6
r: 6
n: 5
r: 30
n: 4
r: 120
n: 3
r: 360
n: 2
720

相关问题:

另见: