call/cc使ってみる

call/ccを実行すると、その時点での継続を捕まえられるらしい。

(call/cc (lambda (cont) body))

ってすると、継続がcontを束縛するらしい。
call/ccの戻り値はbodyだけど、bodyの中でcontが実行された場合はcontの引数がそのまま戻り値になるらしい。
contが複数の引数をとる手続きだったらどうなるんだろう?そんなこと起こり得るのかな?多値が返るのかな?まぁいいや、後で考えよう。


ということで、call/cc使ってみる。次のような簡単な2つの手続きを用意しとく。

(define inc
  (lambda (n) (+ n 1)))
(define twice
  (lambda (n) (* n 2)))

簡単な手続きなので、なんてことない。

gosh> ((lambda (n) (inc (twice n))) 3)
7

さて、じゃぁ(twice n)が済んだ時点での継続を捕まえてみる。

gosh> (define f #f)
f
gosh> ((lambda (n) (inc
                    (call/cc (lambda (cont)
                               (set! f cont)
                               (twice n)))))
       3)
7

(twice n)が終わった時点では、「さっき済んだ計算の結果を使ってincする」ってのが継続。
つまり、

(lambda (m) (inc m))

がfを束縛しているのかな?やってみる。

gosh> (f 1)
2
gosh> (f (twice 3))
7
gosh> (map f '(1 2 3))
2

最後がよくわからん。それ以外は期待通り。