Scheme 手習い 9 章 (2)

p.169 の

(((lambda (mk-length)
   (mk-length mk-length))
 (lambda (mk-length)
  (lambda (l)
   (cond
    ((null? l) 0)
    (else (add 1
           ((mk-length eternity)
            (cdr l))))))))
 l)

を展開してみます。l は (apples) とのこと。
eternity って何だろ。なんてことはとりあえず気にせず展開してみます。
ええと

(lambda (mk-length) (mklength mklength))

な手続きオブジェクトに

(lambda (mk-length)
  (lambda (l)
   (cond
    ((null? l) 0)
    (else (add 1
           ((mk-length eternity)
            (cdr l)))))))

な手続きを戻す手続きオブジェクトが渡されて内側の lambda な手続きオブジェクトの引数 l に (apple) が渡される、と。
Y combinator の仕組みとして自分自身を引数として手続きを戻す手続きオブジェクトを使うことで再起を実装している、と言えば良いのかな。理屈が分かればとても面白い。
さらに以降でもごもごヤッてますね。面白いのは

((lambda (mk-length)
  (mk-length mk-length))
 (lambda (mk-length)
  (lambda (l)
    (cond
      ((null? l) 0)
      (else (add1
              ((mk-length mk-length)
               (cdr l))))))))

(add1
  ((mk-length mk-length)
   (cdr l)))

(add1
  (lambda (x)
    ((mk-length mk-length) x))
  (cdr l))

としておいて、

((lambda (mk-length)
  (mk-length mk-length))
 (lambda (mk-length)
  (lambda (l)
    (cond
      ((null? l) 0)
      (else (add1
              (lambda (x)
                ((mk-length mk-length) x))
              (cdr l)))))))

ここから今追加した手続きオブジェクトをくくり出して

((lambda (mk-length)
  (mk-length mk-length))
 (lambda (mk-length)
  ((lambda (length)
    (lambda (l)
      (cond
       ((null? l) 0)
       (else (add1 (length (cdr l)))))))
    (lambda (x)
     ((mk-length mk-length) x)))))

さらに中のナニをくくり出す。

((lambda (le)
  ((lambda (mk-length)
    (mk-length mk-length))
 (lambda (mk-length)
  (le (lambda (x)
        ((mk-length mk-length) x))))))
 (lambda (length)
   (lambda (l)
    (cond
     ((null? l) 0)
     (else (add1 (length (cdr l))))))))

この手法はなかなか凄いな。
値を取り出して名前を付けるとは言い得て妙。というか 9 章は非常に味わい深い。