現在の継続を取得する手続きがcall-with-current-continuationです。
call-with-current-continuationは長過ぎるので、Gaucheではcall/ccで代用できます。
例えば以下の式、
(begin
(print "first")
(print "second")
(print "third")
'done)
ここで(print "second")を評価した後にやること(継続)は何でしょうか?
(begin
(print "first")
<>
(print "third")
'done)
恐らく
- (print "third")を評価
- 'doneを評価して返す
となるのではないでしょうか?
実はこの後でやること(継続)をcall/ccで取得し、
値として使うことができるのです。
使って確かめてみましょう。
gosh> (define cont 'dummy)
cont
gosh> (begin
(print "first")
(call/cc (lambda (k)
(set! cont k)))
(print "third")
'done)
first
third
done
ここでは、以前(print "second")を評価していたところにcall/ccの式を
入れました。これで(print "second")を評価した後にやることをcall/ccで
取得することができます。
取得した継続は渡された1引数の手続き(lambda (x) ...)に渡
されます。ここの手続きの中では、取得した継続を大域名contに保存して
います。
call/ccは以下のように1引数の手続きを渡して使います。
(call/cc 1引数の手続き)
この手続きにはcall/cc式を評価した後の継続が渡されます。
ここでは継続を保存しただけです。
call/ccの返す値はこの代入式が返す値(#<undef>)です。
contに保存した継続は手続きのように評価することで実行できます。
さっそく保存した継続を動かしてみましょう。
gosh> (cont 'a)
third
done
予想通りの結果だったでしょうか?