call/cc使ってみる3
call/cc 入門 (Coroutine with call/cc) - MAYAHの前半を読んでみた。
演習問題みたいなのがあったので、やってみた。
gosh> (define cont #f) cont gosh> (and (call/cc (lambda (c) (begin (set! cont c) 10))) (begin (display 'a) 10)) a10 gosh> (cont 10) a10
(cont 10)の実行で、何が起きてんのかな?
「call/cc の値を x にしてλ抽象」らしいので、contは
(lambda (x) (and x (begin (display 'a) 10)))
になるかなぁ、と。んで、
実は、continuation は「continuation が呼ばれると、continuation が作られた call/cc の外に、引数を call/cc の返り値としてジャンプする」というのが正しい振る舞いです。
call/cc 入門 (Coroutine with call/cc) - MAYAH
ということらしいけど、これに従うならば、
contが呼ばれると、(call/cc (lambda (c) (begin (set! cont c) 10)))の外に、10をcall/ccの返り値としてジャンプする
という具合になる。 つまり、
(and 10 (begin (display 'a) 10))
ってことになるのかな?
やってみよう。
gosh> (and 10 (begin (display 'a) 10)) a10
うん、同じ結果になった。
同じ要領で、残りの演習もやってみる。
gosh> (define cont #f) cont gosh> (and (begin (display 'a) 10) (call/cc (lambda (c) (begin (set! cont c) 10)))) a10 gosh> (cont 10) 10 gosh> (begin (cont 10) (display 'c)) 10
この場合、contは
(lambda (x) (and (begin (display 'a) 10) x))
だから、(cont 10)は
(and (begin (display 'a) 10) 10)
になるのかな?実行してみる。
gosh> (and (begin (display 'a) 10) 10) a10
あれ?結果が違う。
もいっちょ。(begin (cont 10) (display 'c))は
gosh> (begin (and (begin (display 'a) 10) 10) (display 'c)) ac#<undef>
ん〜?これも違う。
最後。
gosh> (define cont #f) cont gosh> (begin (display 'a) (call/cc (lambda (c) (set! cont c) (display 'b))) (display 'c)) abc#<undef> gosh> (cont #f) c#<undef>
contは
(lambda (x) (begin (display 'a) x (display 'c)))
で、実行してみると
gosh> (begin (display 'a) #f (display 'c)) ac#<undef>
んんんんんん〜?また違う。
もう一回引用するけど、
実は、continuation は「continuation が呼ばれると、continuation が作られた call/cc の外に、引数を call/cc の返り値としてジャンプする」というのが正しい振る舞いです。
これがミソなんだと思うけど、よく理解できない。