星田さんの記事に対するコメント。
そしてLis-refのFold版。うわーっ!そうか!Call/cc! 前に「覚えておこう」とか書いておきながら全然思いつかなかった(^_^;) これこそ使うべき場所だった!と教えていただいた後だと分かるんですが。いや、今回は復習ってのもありますけど前より染み込む気がする。
実際、こういうのは「使う局面」に来ないと思いつかんもんです。
(require (only-in srfi/1 fold iota))
(define (list-ref4 xs n)
(fold (lambda (y z x)
y) (car xs) (cdr xs) (iota n)))
; もちろん iota をわざわざ require せず
; Racket 組み込みの range を使っても良い
で済みます。
まぁ、srfi-1をrequireするのがメンド臭いか否か、ってのは好みの問題になりますね。
あ、前回よりも(比較的)すんなりと入ってくる気がする。継続渡しとかも曖昧だったからこれを機会に明日の夜は継続を学習しよう。
Further Readingとしてこれを推奨しておきます。 => SchemeとActor 理論
これがSmalltalk的なオブジェクト指向の「メッセージ送信」の元ネタで、実はこれを研究する為にSchemeが作られた。
つまり、実は、メッセージ送信、継続渡し、末尾再帰最適化ってのは「全部同じフィールド」に存在する。要するに全部一続きの概念なんです。
この辺が「一般的なオブジェクト指向言語」では決して学べないオブジェクト指向の真髄(少なくとも非常に重要な根幹理論の1つ)です。
是非とも「SchemeとActor理論」を読んで下さい(そして「アクター」がオブジェクト指向プログラミングでの「オブジェクト」そのものです)。