什么决定了Scheme延续的外部边界?

延续的解释通常说延续代表“程序的其余部分”(或类似的措辞)。但显然有一个边界,在这个边界上,继续停止收集这些剩余的计算步骤。那边界是什么?程序的最高级别?或者是其他东西?

这些解释往往以这样的玩具示例开始。

(+ 1 (call/cc
      (lambda (cc)
        (cc 2))))

这计算为3因为(cc 2)意味着“放入2call/cc形式雕刻而成的表达式中的孔中” 。表达式变为(+ 1 2),又名3

现在考虑这个例子:

(define lc #f)
(+ 1 (call/cc
      (lambda (cc)
        (set! lc cc)
        (cc 2))))
(displayln "done")
(lc 42)

在这里,我们将延续存储cc在变量 中lc。在计算表达式后,我们done再次显示并使用延续作为(lc 42)。我们得到什么?

3
done
43
3
done
43

但为什么?如果延续是“程序的其余部分”,为什么延续不捕获 之后发生的所有事情call/cc,包括对displayln和的后续调用lc?在这种解释下,延续将创建一个无限循环。

很明显,事实并非如此。相反,延续似乎正在捕获程序的其余部分,直到它到达随后的表达式,它会忽略(以及任何其他表达式)。

但现在考虑这个例子:

这种情况下的结果是:

3
done
outer
43
done

意思是,延续确实捕获了(displayln "done")in f,尽管它仍然没有捕获(displayln "outer")(lc 42)的调用之后f

最后一个例子——我们将所有内容都移动到一个新函数中g

(define lc #f)
(define (f)
  (displayln (+ 1 (call/cc
                   (lambda (cc)
                     (set! lc cc)
                     (cc 2)))))
  (displayln "done"))
(f)
(displayln "outer")
(lc 42)

这一次,我们得到了前面例子中预测的无限循环:

3
done
outer
43
done
outer
43
···

所以最初的直觉并不完全偏离基础。这只是顶级无望的另一个例子吗?或者是否有更简洁的解释来说明延续的范围?

以上是什么决定了Scheme延续的外部边界?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>