TheSeasonedSchemer (6)

chapter 16 を読んだとの連絡が入ったので確認。

前半分の memoize なソレはスルー。というか、後ろ半分の Y-bang も若干微妙ですが。

後ろ半分

thunk を実行する thunk な手続きオブジェクトがキモ。というか色々な意味で卑怯。
最終的に出てくる Y-bang が以下。

(define Y-bang
  (lambda (f)
    (letrec
      ((h (f (lambda (arg) (h arg)))))
      h)))

何が卑怯かというと f によって h が書きかわってしまって f に渡されている手続きオブジェクトの中の h も書きかえられる、ということ。λ 凄いよ λ と言えば良いでしょうか。
例えば Y-bang にテキストで例示されてる以下の L が渡される場合

(define L
  (lambda (length)
    (lambda (l)
      (cond
        ((null? l) 0)
        (else (add1 (length (cdr l))))))))

んーと、L が戻す手続きオブジェクトが h に束縛、というか戻す手続きオブジェクトは

(lambda (l)
  (cond
    ((null? l) 0)
    (else (add1 ((lambda (arg) (h arg)) (cdr l))))))

で、これが h 自身である (というのはやや不正確?)、というのが面白い。
# ええと、直感的な感想でスミマセン
id:h6n なエントリにある_新しいhになる前のhの値そのものをLに渡してしまわないように、lambdaでくるんでる?_という記述がソレかな、と。

備忘

Y と Y! の比較はScheme修行16章なエントリをご確認下さい。わしも余裕があれば確認してみます。