我在理解以下行为方面遇到了一些麻烦 计划方案:
(define c
(dynamic-wind
(lambda () (display 'IN)(newline))
(lambda () (call/cc (lambda (k)
(display 'X)(newline)
k)))
(lambda () (display 'OUT)(newline))))
据我所知,c将被绑定到“(显示'X)”之前创建的连续符。
但是使用c似乎可以自我修改!上面的定义打印(如我所料)IN,X和OUT:
IN
X
OUT
这是一个程序:
#;2> c
#<procedure (a9869 . results1678)>
现在,我希望当它再次被调用时,X会打印出来,而不是!
#;3> (c)
IN
OUT
现在c不再是一个程序了,c的第二次调用将不起作用!
#;4> c ;; the REPL doesn't answer this, so there are no values returned
#;5> (c)
Error: call of non-procedure: #<unspecified>
Call history:
<syntax> (c)
<eval> (c) <--
我期待(c)的每次调用都会做同样的事情 - 打印IN,X和OUT。我错过了什么?
答案 0 :(得分:8)
在Racket中运行它会更有帮助:
-> (define c
(dynamic-wind
(lambda () (display 'IN)(newline))
(lambda () (call/cc (lambda (k)
(display 'X)(newline)
k)))
(lambda () (display 'OUT)(newline))))
IN
X
OUT
-> c
#<continuation>
-> (c)
IN
OUT
define-values: context (defining "c") expected 1 value, received 0 values
-> (c 99)
IN
OUT
-> c
99
请特别注意c
绑定到一个连续值 - 因为您的表达式返回k
作为值。并且k
本身是值表达式的延续,这意味着此延续是等待将值绑定到c
的延续。所以调用它需要一个值,正如Racket所要求的那样,这有助于澄清这里发生的事情(MIT Scheme似乎默默地将其视为未指定)。无论如何,在99上应用此延续意味着该表达式的返回值为99 - 因此您跳回上下文(打印IN
)并返回99 以绑定到c
< / em>,并在出路时打印OUT
。您现在已将c
修改为99,而不是第三次调用它。