よーしパパ、関数に名前を付けずに再帰させちゃうぞぉ!(その8)
今日は体調が悪かったので、仕事を休んだ。
おかげで布団に入って、脳内でいくらでもscheme出来たよ。
その結果、自分のやり方に限界があったんじゃないってことに気づいた。
((lambda (mk-length) (mk-length mk-length)) (lambda (mk-length) (lambda (l) (cond ((null? l) 0) (else (+ 1 ((mk-length mk-length) (cdr l))))))))
これは、
((lambda (f) (f f)) hoge)
を
(hoge hoge)
に書き直すのとおんなじ要領で、
((lambda (mk-length) (lambda (l) (cond ((null? l) 0) (else (+ 1 ((mk-length mk-length) (cdr l))))))) (lambda (mk-length) (lambda (l) (cond ((null? l) 0) (else (+ 1 ((mk-length mk-length) (cdr l))))))))
となる。これも同じ要領で1行目のmk-lengthを消したいな、ってことで
(lambda (l) (cond ((null? l) 0) (else (+ 1 (((lambda (mk-length) (lambda (l) (cond ((null? l) 0) (else (+ 1 ((mk-length mk-length) (cdr l))))))) mk-lengthって書きたい) (cdr l))))))
「mk-lengthって書きたい」ってところは
(lambda (mk-length) (lambda (l) (cond ((null? l) 0) (else (+ 1 ((mk-length mk-length) (cdr l)))))))
になるはずだから、それを素直にブチ込めばいいのね。たぶん。
ということでやってみる。
(lambda (l) (cond ((null? l) 0) (else (+ 1 (((lambda (mk-length) (lambda (l) (cond ((null? l) 0) (else (+ 1 ((mk-length mk-length) (cdr l))))))) (lambda (mk-length) (lambda (l) (cond ((null? l) 0) (else (+ 1 ((mk-length mk-length) (cdr l)))))))) (cdr l))))))
だね。見覚えある形が関数の中に出てきてるな。
再帰構造が見えてきたような気がする。
関数の評価が再帰するんじゃなくて、構造そのものが再帰してるという凶悪さ。
無名関数を再帰させるってのはそういうことなのかな?
これはムズい。
eternityのときはこの要領で書き直していくといつか終わってたけど、これはたぶん終わりそうにないな。
どこまでもmk-lengthが出てくるっぽい。
でも今までの経験上、schemeは関数の中に定義されていない関数が含まれていても、実際にそれを評価しないのならエラーにならなかった。
いつかはlがnullになって0に評価され、再帰評価しない時が来るから、関数の定義が無限に長くならずに済むんだろうな。
たしかに自分のやり方が悪かったわけじゃないけど、賢明なやり方ではないような気がする。
schemerはこの種の関数を考えるときには、どんな思考過程を辿るのだろう。
気になる。