JavaScriptとSchemeのアレ
http://q.hatena.ne.jp/1180098481
http://d.hatena.ne.jp/amachang/20090119/1232331329
同じ様なのに以前引っかかった事があったりで・・・。
同じ感じのコードをSchemeで書いてみて実行してみました
(define a #f) (set! a (make-vector 10)) (define (f1 num) (define (f-iter num acc) (if (= num acc) (begin (display "end!") 'done) (begin (vector-set! a acc (lambda () (display acc))) (f-iter num (+ acc 1)) ))) (f-iter num 0)) (define (f2 num) (let ((i 0)) (while (< i num) (vector-set! a i (lambda () (display i))) (set! i (+ i 1))))) (define (f3 num) (let ((i 0)) (while (< i num) (vector-set! a i ((lambda (i_) (lambda () (display i_))) i)) (set! i (+ i 1)))))
f1とf3の時は
((vector-ref a 0)) => 0
という具合ですが、f2の時は
((vector-ref a 0)) => 10
という。
この辺を、割としっかりと説明してくれる人がいると素晴らしいんじゃないかなっていう。
私だと言葉足らずというのと、合ってるかどうかも分からん。
色々書いてみる
f2では適切なスコープ中の識別子を探し始める段階で既にiが10になってしまってるとかそういう。
で、確かこの辺はgaucheではdisasmかcompileなんたらをするとgrefかlrefで実際に見る事が出来た気がします。
うん。こんなのでは説明に成ってない感じだな。仕方ないね。
http://wiki.monaos.org/index.php?Reading%20Gauche%2Fvm%2Finsn%2FGREF
えーとつまり
f2の中の (vector-set! a i (lambda () (display i)))
でiには0..9な値が入っている訳では無いんですよ!!という感じですね。
一方f3だと無理矢理それをさせているというか。
これであってるんだろうか。