开发者

Help with dynamic-wind and call/cc

I am having some trouble understanding the behavior of the following Scheme program:

(define c
  (dynamic-wind
    (lambda () (display 'IN)(newline))
    (lambda () (call/cc (lambda (k)
                     (display 'X)(newline)
                     k)))
    (lambda () (display 'OUT)(newline))))

As I understand, c will be bound to the continution created right before "(display 'X)".

But using c seems to modify itself! The define above prints (as I expected) IN, X and OUT:

IN
X
OUT

And it is a procedure:

#;2> c
#<procedure (a9869 . 开发者_StackOverflow社区results1678)>

Now, I would expect that when it is called again, X would be printed, and it is not!

#;3> (c)
IN
OUT

And now c is not a procedure anymore, and a second invokation of c won't work!

#;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)    <--

I was expecting that each invokation to (c) would do the same thing -- print IN, X, and OUT. What am I missing?


Running this in Racket is a little more helpful:

-> (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

Note specifically that c gets bound to a continuation value -- because your expression returns k as the value. And k itself is the continuation of the value expression, which means that this continuation is the one waiting to get a value to be bound to c. So invoking it requires a single value, as Racket requires, which helps clarifying what happens here (MIT Scheme seems to silently treat it as unspecified). Anyway, applying this continuation on 99 means that the return value from that expression is 99 -- so you jump back into the context (printing IN) and return 99 to be bound to c, and print OUT on your way out. You've now modified c to have that 99 instead, so you can't call it a third time.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜