星田さんの記事に対するコメント。今回は一箇所だけ。
これ・・やっぱり同じじゃないよなぁ。ま、良いか(^_^;) 厳密な定義を再現するとかが目的でもないしな・・。ちょっと後でCametanさんに引数の逆転の一件で示してもらった定義を探してみよう。
理由はハッキリしてる。fold1の再帰部分のprocの引数の順番が逆、なんだ。
;; 再帰中の proc が取る引数の順序が逆(define (fold1 proc a xs)
(if (null? xs)
a
(fold1 proc (proc (car xs) a) (cdr xs))))
何度も言うけど、procの引数が関数foldの引数の順序と逆になる。
言い換えると、+ とか * とかの「交換法則」が成り立つ関数でテストすると、このバグは見つかりづらい。「交換法則」が成り立つ、って事は、左から計算しようと右から計算しようと同じだからね。
- 1 +2 = 2 + 1
- 1 * 2 = 2 * 1
一方、consは交換法則が成り立たない。
- (cons 'a '()) ≠ (cons '() 'a)
結果、foldを書く時、汎用目的でprocを適用する際、引数順序を気にしないといけない。あくまで第二引数が「初期値」になって、リストから取ってきたcar部分をcons(に限らないけど)出来るように書かないとならないわけ。
恐らく、オリジナルのコードで、うっかり手癖で書いちゃったんでしょう。fold1の引数順序をつい、うっかり「正順で」書いちゃったんだな。
それがバグの原因です。