Gaucheリハビリ

さて結局お子様に全てをささげることとなった昨日。。。。。。なーんもできなかぁったよぉおお*1
今日はお仕事がんばるぞ、と思ったら、まだ設計データの権利問題でゴタゴタしてるらしい。こればかりは僕の頭の上の戦いなので手の出しようが無い。仕方ないのでsimだけ走らせておいて持って来ておいた「プログラミング Gauche」にうつつを抜かしてみる*2
・・・・というかとりあえずリハビリしないと激しく感覚鈍ってて進まないっぽい。まずはfoldから。末尾再起なのとそうじゃないのを書いてみる。
末尾再起版(というかfoldl)の僕の理解の仕方はベルトコンベア。ベルトコンベアに乗ったリスト(下ではinit)が次々と次の段(fold再起)を流されていってデコレートされていく、というイメージ。んで材料(lst)が尽きたらデコレートされ終わった「できあがりリスト」を返す。

(define (fold f init lst)
        (if (null? lst) init   ; できあがりリストを返す。
            (fold f (f (car lst) init) (cdr lst))))   ; デコレート (f (car lst) init) して次の段へ
>(fold + 0 (iota 100 1))
5050
>(fold cons '(end) '(a b c d e f))
(f e d c b a end)

ちゃんとひっくり返ってる。おkだ。

じゃない版(というかfoldr)は後ろ今の式を後回しにして、とりあえず処理を進める。後ろの値は後ろの関数に丸投げして任せっきり。自分は自分のみ担当あとは知らん。という書き方。
イメージどおり f(x0, f(x1, f(x2, ......))) が計算機内部で再現される。スタック食い。

(define (fold2 f init lst)
	(if (null? lst) init
	    (f (car lst) (fold2 f init (cdr lst)))))
> (fold2 cons '(end) '(a b c d e f))
(a b c d e f end)

ひっくり返ってなーい。おkだ。だいぶ思い出してきたかも。
つぎlength

(define (length lst)
	(if (null? lst) 0
	    (+ 1 (length (cdr length))))

さらにfilter

define (filter pred lst)
	(cond [(null? lst) '()]
	      [(pred (car lst)) (cons (car lst) (filter pred (cdr lst)))]
	      [else (filter pred (cdr lst))]))
> (filter odd? '(2 4 5 8  10 111 115 110 ))
(5 111 115)

激しく non-DRY になってる気もするけどまあ良いや。だいぶ思い出してきた。
一気にいくぞぉ。。。
6章本文にもあった reverse の末尾再起版

 (define (reverse lst)
	(define (inner lst ret)
	  (if (null? lst) ret
	      (inner (cdr lst) (cons (car lst) ret))))
	(inner lst '()))

いいんだろうかこんなんで。。。

*1:いいんだけどね。別に

*2:と思ったらsimがハングしてる。やだなあ、また解析か