帮助动态风和呼叫/ cc

jos*_*osh 4 scheme continuations racket

我在理解以下Scheme程序的行为时遇到了一些麻烦:

(define c
  (dynamic-wind
    (lambda () (display 'IN)(newline))
    (lambda () (call/cc (lambda (k)
                     (display 'X)(newline)
                     k)))
    (lambda () (display 'OUT)(newline))))
Run Code Online (Sandbox Code Playgroud)

据我所知,c将被绑定到"(display'X)"之前创建的连续符.

但是使用c似乎会改变自己!上面的定义打印(如我所料)IN,X和OUT:

IN
X
OUT
Run Code Online (Sandbox Code Playgroud)

这是一个程序:

#;2> c
#<procedure (a9869 . results1678)>
Run Code Online (Sandbox Code Playgroud)

现在,我希望当它再次被调用时,X会打印出来,而不是!

#;3> (c)
IN
OUT
Run Code Online (Sandbox Code Playgroud)

现在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)    <--
Run Code Online (Sandbox Code Playgroud)

我期待(c)的每次调用都会做同样的事情 - 打印IN,X和OUT.我错过了什么?

Eli*_*lay 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
Run Code Online (Sandbox Code Playgroud)

特别注意,它c被绑定到一个连续值 - 因为你的表达式返回k值.并且k它本身是值表达式的延续,这意味着这个延续是等待获取值绑定的那个c.所以调用它需要一个值,正如Racket所要求的那样,这有助于澄清这里发生的事情(MIT Scheme似乎默默地将其视为未指定).无论如何,在99上应用此延续意味着该表达式的返回值为99 - 因此您跳回到上下文(打印IN)并返回99 以进行绑定c,并OUT在出路时打印.你现在已修改c为99,所以你不能第三次调用它.