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 comments :

nobsun said...

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

k16 said...

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

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

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