在过去的几天里,我一直在玩弄计划(特别是诡计)的延续,并且对于某些函数的结果感到有点困惑并且想知道是否任何人都可以解释到底发生了什么。计划:如何使用call/cc进行回溯
有一个名为(get-token)
将在一个给定的文件检索发现旁边标记功能。例如,如果接下来的3个标记是“a”,“b”和“c”,调用(get-token)将在第一次调用时返回“a”,第二次调用时返回“b”和“c”第三次被称为。
我想要做的是有一个函数(peek-token)
,将调用(get-token)
,返回令牌,然后返回到调用(get-token)
函数之前的状态。我尝试了许多不同的方法来实现这一结果,和我目前拥有的是:
;; make things a little easier to write
(define-syntax bind/cc
(syntax-rules()
((bind/cc var . body)
(call/cc (lambda (var) . body)))))
;; function should return next token and then
;; revert to previous state
(define (peek-token)
(bind/cc return
(let ((token (get-token)))
(return token))))
我现在如何的理解,bind/cc
将在第一return
保存的延续,然后执行以下代码块。然后当return
再次被击中时,程序跳回到连续被绑定的位置,并且结果给出token
值。
然而,当我运行上面的函数的结果是完全一样的原始(get-token)
功能。
我会很感激,如果任何人都可以解释我要去的地方错了,或者表达一种更好的方法来获得相同的结果(我知道有些人讨厌去呼叫/立方厘米的方式)。
非常感谢你的帮助。我最终将'(peek-token)'函数放在我的扫描器文件中,并且只是跟踪文件指针,以便我可以从中重新读取令牌。出于好奇,你是否知道一种方法来捕获任一方案或CL中的实际程序状态?或者从来没有真正需要这个? – vikingsheepman
除非我弄错了形式'(call-cc(lambda(k)...(k x)))'与'(begin ... x)'完全相同的任何形式。 – jozefg
@jozefg非常多,假设这是继续使用的唯一地方。 –