継続わからない...
現在Gauche第19章6節に取り組み中なのだが,継続がいまいち分からない.特に
(define-syntax for-each-ext (syntax-rules () [(_ break next lambda-expr arg-list ...) (let ((arg1 (list arg-list ...))) (call/cc (lambda (break) (apply for-each (lambda arg (call/cc (lambda (next) (apply lambda-expr arg)))) arg1))))])) (for-each-ext break1 next1 (lambda (x) (for-each-ext break2 next2 (lambda (y) (cond [(not (number? x)) (next1 x)] [(not (number? y)) (next2 y)] [(< x y) (break2)] [(>= x 100) (break1 (display 'done))] [else (format #t "~2d " (* x y))])) '(1 2 3 a 4 5 b 6 7 c 8 #\a 9 '() 10)) (newline)) '(#\x 1 2 3 a 4 5 6 y 7 8 9 10 z 100))
動きはなんとなーくわかる気がするのだが,ちゃんと見るとわからくなる.
マクロで定義している block の動きがよくわからない.
(let ((arg1 (list arg-list ...))) (call/cc (lambda (break) (apply for-each (lambda arg (call/cc (lambda (next) (apply lambda-expr arg)))) arg1))))]))
の部分は,arg-list ... をarg1にして,breakを継続にして,applyを実行.
applyでは,arg1がfor-eachで廻されて,lambdaに適応される.lambdaでは,nextを継続にして,apply lambda-exprを実行.(動きがよくわかっていないため,日本語もあべこべ)
breakが来ていないのに,それ以降がなぜ実行されるの?
そもそも継続自体がやっぱりよくわかっていなくて,
ここにある
(define cont #f) (+ (* 1 2) (call/cc (lambda (c) (set! cont c) (* 3 4))))
は,call/ccの前にある (+ (* 1 2) への継続がcに渡されることはわかる.そして, (set! cont c) により, contが (+ (* 1 2) への継続となることはわかる.
しかし,gauche P.283の
(define (breaker/cc proc break) (lambda (elt seed) (call/cc (lambda (cont) (set! next (lambda () (cont (proc elt seed)))) (break #f))))) (define (process elt seed) (print "found: " elt) (cons elt seed)) (define (find-fold pred? proc seed lis) (cond [(null? lis) seed] [(pred? (car lis)) (let ((seed2 (proc (car lis) seed))) (find-fold pred? proc seed2 (cdr lis)))] [else (find-fold pred? proc seed (cdr lis))])) (call/cc (lambda (cont0) (find-fold odd? (breaker/cc process cont0) '() '(1 2 3 4 5 6))))
のcont0や,contはどこへの継続なのだろう..どこへも継続していないんだね?
breaker/cc の (break #f)で cont0 を受けるわけだが,とりあえず,#fを評価してくれということなのか..
何回そこらへんを読んでもやっぱりわからない.
靴が脱げないところで,足が痒くてたまらないのに,でも掻けない!って感じがしている.