Next: 8.5 Call/CCによる自動バックトラック
Up: 8 Continuation(継続)
Previous: 8.3 無限の ExtentをもつContinuation
CommonLispのCatch, Throwを用いる例として,
(defun print-table (l)
(catch 'not-a-number
(mapcar #'print-sqrt-abs l)))
(defun print-sqrt-abs (x)
(print (sqrt (abs (must-be-number x)))))
(defun must-be-number (x)
(if (numberp x) x
(throw 'not-a-number "huh?")))
<cl> (print-table '(1 -2 a 10))
1.0
1.4142135
"huh?"
というように,数以外のものがきたらそこで中断して
catchへ戻ってくるものを作ることができます.
これと同じことは,
<cl> (scheme-interpreter)
==> (define (print-table l)
(call/cc
(lambda (escape)
(set! not-a-number escape)
(map print-sqrt-abs l))))
PRINT-TABLE
==> (define (print-sqrt-abs x)
(write (sqrt (abs (must-be-number x))))
(newline))
PRINT-SQRT-ABS
==> (define (must-be-number x)
(if (number? x) x
(not-a-number "huh?")))
MUST-BE-NUMBER
==> (define (map fn l)
(if (null? l)
nil
(cons (fn (car l))
(map fn (cdr l)))))
MAP
==> (print-table '(1 -2 a 10))
1.0
1.4142135
"huh?"
==>
というぐあいにcall/ccを用いて作ることができます.
つまり,catchしたいところで,call/ccを行い,
そこでのcontinuationを大域変数に保存し,
そのcall/ccへ戻りたいところで,その大域変数
に保存したcontinuationを実行するという形で
実現が可能です.
generated through LaTeX2HTML. M.Inaba 平成18年5月6日