【发布时间】:2021-10-17 01:51:07
【问题描述】:
对于延续的解释,通常会说延续代表“rest of the program”(或类似的措辞)。但显然有一个边界,延续停止收集这些剩余的计算步骤。 边界是什么?程序的顶层?还是别的什么?
这些解释往往从这样一个玩具示例开始。
(+ 1 (call/cc
(lambda (cc)
(cc 2))))
计算结果为3,因为(cc 2) 的意思是“将2 放入由call/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
但是……为什么?如果延续是“程序的其余部分”,为什么延续不捕获call/cc 之后发生的所有事情,包括随后对displayln 和lc 的调用?在这种解释下,延续将创建一个无限循环。
显然,事实并非如此。相反,似乎延续正在捕获程序的其余部分直到它到达后续表达式,它会忽略(以及任何其他表达式)。
但现在考虑这个例子:
(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
意思是,延续确实捕获f中的(displayln "done"),尽管在调用f之后它仍然没有捕获(displayln "outer")和(lc 42)。
最后一个例子——我们将所有内容移入一个新函数g:
(define lc #f)
(define (g)
(define (f)
(displayln (+ 1 (call/cc
(lambda (cc)
(set! lc cc)
(cc 2)))))
(displayln "done"))
(f)
(displayln "outer")
(lc 42))
(g)
这一次,我们得到了前面例子中预测的无限循环:
3
done
outer
43
done
outer
43
···
所以最初的直觉并不是完全偏离基础的。这只是top level being hopeless 的另一个实例吗?或者有没有更简洁的解释来说明延续达到的程度?
【问题讨论】:
-
我不是专家,但我认为“未定界”延续传统上由正在评估的单个顶级表单或返回到解释器中的提示来定界。
-
我相信我在这里含蓄地回答了您当前的问题stackoverflow.com/questions/68969657/…
标签: scheme racket continuations