Gauche を update.
昨日の、
Compile Error: [internal error] stray local variable:
の件で shiro さんからコメントを頂きました。ありがとうございます。
0.8.6 以前では、コンパイラの最適化ルーチンのバグで、このエラーが発生することがあるとのことです。
http://www.shiro.dreamhost.com/scheme/gauche/index-j.html を拝見したところ、
- ローカル関数のインライン展開が重なった場合にInternal compiler error が出るバグがコンパイラにありました (Thanks to Jun Inoue for tracking this down)。他にもいくつかInternal compiler errorとなり得るバグを修正しています。
これらしいですね。
ちゃんと確認して update していれば、自分で解決できたかもしれないというのに、shiro さん直々にコメント頂くことになり申し訳ありませんでした。
早速、update して確認致しました。
(use gauche.config) #<undef> (gauche-version) "0.8.7"
となった状態で、
(let () (define (make-counter init incremental) (let ((x init) (y incremental)) (lambda () (set! x (+ x y))))) (define c1 (make-counter 0 1)) (define c2 (make-counter 0 2)) (let loop ((n 10)) (if (< n 0) #f (begin (if (even? n) (print "(c1) => " (c1)) (print "(c2) => " (c2))) (loop (- n 1)))))) (c1) => 1 (c2) => 2 (c1) => 2 (c2) => 4 (c1) => 3 (c2) => 6 (c1) => 4 (c2) => 8 (c1) => 5 (c2) => 10 (c1) => 6 #f
となり、意図した通りの動作をしてくれました。
一応、昨日作っておいたスクリプト、
$ cat closure-5.scm #!/usr/bin/env gosh ; (define (main args) (define (make-counter init incremental) (let ((x init) (y incremental)) (lambda () (set! x (+ x y))))) (define c1 (make-counter 0 1)) (define c2 (make-counter 0 2)) (let loop ((n 10)) (if (< n 0) #f (begin (if (even? n) (print "(c1) => " (c1)) (print "(c2) => " (c2))) (loop (- n 1)))))) ;; Ends here.
も実行してみました。
インタラクティブに動かしたものと内容は同じですが、`main' 手続きで包んでいます。
$ ./closure-5.scm (c1) => 1 (c2) => 2 (c1) => 2 (c2) => 4 (c1) => 3 (c2) => 6 (c1) => 4 (c2) => 8 (c1) => 5 (c2) => 10 (c1) => 6
こちらも問題無し、意図した通りに動作してくれている様です。
斯くして問題は無事解決致しました。
しかし、ML や BTS などに報告した訳でもないのに開発者の方から直々にコメントを頂けて問題を解決できてしまうとは、何とも幸せな時代になったものですね。これまでにも何度もコメントを頂いていて、あっと言う間に疑問が氷解していますし、誤解についてもすぐに訂正して頂けたりで、本当にありがたい事です。
それも shiro さんが常にアンテナを張っておられて、訳の判らん者が勝手なことを書いている blog にまで目を通しておられるからで、利用者としては嬉しい限りです。ありがとうございました。