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 . 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With