継続利用の具体例:大域脱出
code:gauche
(h
(call/cc
(lambda (cont-proc) ;; 継続手続きをとり出す
(let ((v (f 入力)))
(cont-proc 1) ;; 継続手続きに1を渡す
(g v) ;; ここでgを呼び出しているが、
)))) ;; 直前の継続手続きで脱出してしまうため、実際には実行されない
=> (h 1)
継続を呼ぶということは、次の処理へ進む、ということを意味する、ということか
だからg vは呼ばれない
このコードだけ見るとg vをわざわざ書いている意味がないので、「こんなコード書くこと有るの?」になってしまうが、実際はloopのなかとかで条件によってこんなことをするんだろう
code:lisp
(define-syntax block
(syntax-rules ()
[(block escape body ...)
(call/cc (lambda (escape) body ...))]))
call/ccに変換されるマクロ
escapeの部分に指定したキーワードが、escape用のキーワードになる
日本語で説明しづらい
Cとかのswtich文におけるbreakというキーワードを自分で定義できる感じ
call/ccによって継続を取得するが、
code:lisp
(block escape-top
(block escape-1st
(block escape-2nd
(escape-1st 1)
(print 'NG!!!!)
)
(print 'NG!!)
)
(print 'OK))
code:lisp
(+ 1 2 (block return
(print 'one)
(print 'two)
(return 3)
(print 'four))
4)
こんな感じに展開される
code:lisp
(+ 1 2 (call/cc (lambda (return)
((print 'one)
(print 'two)
(return 3)
(print 'four))))
4)
挙動が若干違うので多分間違ってるけど