2007/03/05

先月、連番を作るのにintegというプロシージャを定義して喜んでいたら、素直な方法はこれだという指摘をいただいた。ありがとうございます。
(define integ
(let ((n 0))
(lambda ()
(set! n (+ n 1))
n)))
なるほど。これはきっともう一度"Seasoned Schemer"を読み直すべきだな。

ところで、こういうクロージャをSICPの第3章の評価モデルで表すとどうなるんだろう。
まず考えやすいようにletをlambdaに変換して、
(define integ
((lambda (n)
(lambda ()
(set! n (+ n 1))
n))
0))
nが0に束縛された環境以下でset!が機能するのだから、こんな感じでいいのだろうか?

integ-1

2 件のコメント:

  1. (define f
     (let ((local-var init))
      (lambda args body)))
    で関数に局所状態をもたせるというのはSICPにも出てくるパターンですね。
    ところで、
    gosh> (list (integ) (integ) (integ))
    (1 2 3)
    は,R5RSには引数の評価順が規定されていないので,これが
    (3 2 1)になっても文句はいえないと思う:)

    返信削除
  2. どれだけザル読みかって話ですね。>SICPにも出てくるパターン

    > R5RSには引数の評価順が規定されていない

    そうでした。SICPにも評価順を逆にする練習問題がひとつといわずあったような。そういえば"On Lisp"の継続の章あたりでもSchemeの特徴として触れられてますね。

    返信削除