2010/03/09

TSS intersectall (letcc, call/cc)

letcc の hop を catch, hop の呼び出しを throw だ、と言われると途端にイメージが出来上がった。しかし、たぶんC#なんかの catch, throw と同じようなこともできるだけで、同じではない、ですよね。

未だに継続周り(呼び出しとか渡しとか)が、いまいちピンとこない。
説明やコードを読めば、その時は動きがわかるし、何をしてるかもだいたいわかる(つもり)。
見よう見まねで書ける。

でも消化不良(?)というか、ものにならないというか。
パラダイムシフトが起きてないってことなのかな。

で、それが起きないのはそれが起きるほどコードを書いてないから、だと思う。

「悟り体験」ってきっとパラダイムシフト。

; intersectall
; The Seasoned Schemer
(define intersectall
(lambda (lset)
(cond
((null? lset) '())
((null? (cdr lset))(car lset))
(else (intersect (car lset)
(intersectall (cdr lset)))))))
(intersectall '((tomatoes and macaroni)
(macaroni and cheese)))
; -> (and macaroni)
; The Seasoned Schemer letrec
(define intersectall
(lambda (lset)
(letrec
((A (lambda (lset)
(cond
((null? (cdr lset))
(car lset))
(else (intersect (car lset)
(A (cdr lset))))))))
(cond
((null? lset)(quote ()))
(else (A lset))))))
(intersectall '((tomatoes and macaroni)
(macaroni and cheese)))
; -> (and macaroni)
; The Seasoned Schemer letcc
; letcc -> gauche let/cc
(define letcc let/cc)
(define intersectall
(lambda (lset)
(let/cc hop ; L:(catch 'hop)
(letrec
((A (lambda (lset)
(cond
((null? #?=(car lset))
(hop (quote ()))) ; L:(throw 'hop (quote ()))
((null? (cdr lset))
(car lset))
(else
(intersect (car lset)
(A (cdr lset))))))))
(cond
((null? lset)(quote ()))
(else (A lset)))))))
(intersectall '((3 mangos and)
(3 kiwis and)
(3 hamburgers)))
;; #?="(stdin)":252:(car lset)
;; #?- (3 mangos and)
;; #?="(stdin)":252:(car lset)
;; #?- (3 kiwis and)
;; #?="(stdin)":252:(car lset)
;; #?- (3 hamburgers)
;; (3)
(intersectall '((3 steaks and)
(no food and)
(three baked potatoes)
(3 diet hamburgers)))
;; #?="(stdin)":252:(car lset)
;; #?- (3 steaks and)
;; #?="(stdin)":252:(car lset)
;; #?- (no food and)
;; #?="(stdin)":252:(car lset)
;; #?- (three baked potatoes)
;; #?="(stdin)":252:(car lset)
;; #?- (3 diet hamburgers)
;; ()
(intersectall '((3 mangoes and)
()
(3 diet hamburgers)))
;; #?="(stdin)":252:(car lset)
;; #?- (3 mangoes and)
;; #?="(stdin)":252:(car lset)
;; #?- ()
;; ()
; letcc -> call-with-current-continuation
(define intersectall
(lambda (lset)
(call-with-current-continuation
(lambda (hop)
(letrec
((A (lambda (lset)
(cond
((null? #?=(car lset))
(hop (quote ())))
((null? (cdr lset))
(car lset))
(else
(intersect (car lset)
(A (cdr lset))))))))
(cond
((null? lset)(quote ()))
(else (A lset))))))))
(intersectall '((3 mangos and)
(3 kiwis and)
(3 hamburgers)))
;; #?="(stdin)":279:(car lset)
;; #?- (3 mangos and)
;; #?="(stdin)":279:(car lset)
;; #?- (3 kiwis and)
;; #?="(stdin)":279:(car lset)
;; #?- (3 hamburgers)
;; (3)
(intersectall '((3 steaks and)
(no food and)
(three baked potatoes)
(3 diet hamburgers)))
;; #?="(stdin)":279:(car lset)
;; #?- (3 steaks and)
;; #?="(stdin)":279:(car lset)
;; #?- (no food and)
;; #?="(stdin)":279:(car lset)
;; #?- (three baked potatoes)
;; #?="(stdin)":279:(car lset)
;; #?- (3 diet hamburgers)
;; ()
(intersectall '((3 mangoes and)
()
(3 diet hamburgers)))
;; #?="(stdin)":279:(car lset)
;; #?- (3 mangoes and)
;; #?="(stdin)":279:(car lset)
;; #?- ()
;; ()
(define intersectall
(lambda (lset)
(letrec
((A (lambda (lset)
(cond
((null? #?=(car lset))
'())
((null? (cdr lset))
(car lset))
(else
(intersect (car lset)
(A (cdr lset))))))))
(cond
((null? lset)(quote ()))
(else (A lset))))))
(intersectall '((3 mangos and)
(3 kiwis and)
(3 hamburgers)))
;; #?="(stdin)":323:(car lset)
;; #?- (3 mangos and)
;; #?="(stdin)":323:(car lset)
;; #?- (3 kiwis and)
;; #?="(stdin)":323:(car lset)
;; #?- (3 hamburgers)
;; (3)
(intersectall '((3 steaks and)
(no food and)
(three baked potatoes)
(3 diet hamburgers)))
;; #?="(stdin)":323:(car lset)
;; #?- (3 steaks and)
;; #?="(stdin)":323:(car lset)
;; #?- (no food and)
;; #?="(stdin)":323:(car lset)
;; #?- (three baked potatoes)
;; #?="(stdin)":323:(car lset)
;; #?- (3 diet hamburgers)
;; ()
(intersectall '((3 mangoes and)
()
(3 diet hamburgers)))
;; #?="(stdin)":323:(car lset)
;; #?- (3 mangoes and)
;; #?="(stdin)":323:(car lset)
;; #?- ()
;; ()


この例の場合だと、最後のコードでも同様の結果・・・ですよね?
ネストが深い場合に、深部から一気に脱出するとなると継続呼び出しの方でないとできない・・・んだよねきっと。

0 件のコメント:

コメントを投稿