さかもとのブログ

つらつらと

継続わからない...

現在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を評価してくれということなのか..
何回そこらへんを読んでもやっぱりわからない.

靴が脱げないところで,足が痒くてたまらないのに,でも掻けない!って感じがしている.