よーしパパ、関数に名前を付けずに再帰させちゃうぞぉ!(その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はこの種の関数を考えるときには、どんな思考過程を辿るのだろう。
気になる。