Let's start Scheme

2014-07-14

ライブラリの作られるタイミング

Chaton Gauche部屋から流れてきたこれ
REPLからエラーの起きるライブラリを繰り返しr7rs#importすると,エラーが起きなくなります.

;; temp.scm
(define-library (temp)
  (begin
    (f)))

;; REPL
gosh> (import (temp))
*** ERROR: Compile Error: Compile Error: unbound variable: f

"(standard input)":1:(import (temp))

Stack Trace:
_______________________________________
  0  (eval expr env)
        At line 179 of "/usr/local/share/gauche-0.9/0.9.4-rc2/lib/gauche/interactive.scm"
gosh> (import (temp))
#<undef>
gosh[r7rs.user]>
全く同じ問題がSagittariusでも起きる。原因も分かっていて、コンパイラがコンパイル時にライブラリを作ってしまうけど、エラー自体はランタイムで起きるのでimportが呼ばれた際にはライブラリはあるものとして扱われてしまうから。

あまりうまい解決策が思いつかないんだけど、とりあえずぱっと思いついたのがVM側で何とかするというもの。っが、実際に実装しかけては無理だなぁということが分かってしまったので破棄。案としては、evalの中身をwith-exception-handlerで囲ってしまい、エラーが起きた際に現在のライブラリと保存されたライブラリが異なっていたら現在のライブラリを破棄するというもの、だったのだが、これはライブラリの変更がインストラクションでのみ発生するということに依存している上に、それ以外の方法で変更することが可能なので火を見るより明らかにだめだろうという・・・

次に思いついたのが、ライブラリのコンパイル全体をwith-exception-handlerで囲ってしまうとうもの。実際の手順としては以下のようになる予定。
  • ダミーのライブラリを作る
  • 実行コードをwith-exception-handlerで囲う
  • コンパイル及び実行
    • エラーがあればダミーを破棄
    • なければ正式名で作成及び中身をコピー
こっちはまだ実装をしていないのだが、見えているだけで以下のデメリットががが
  • エラーが存在しない場合でも呼ばれる
    • キャッシュがでかくなる
  • 余分な手続きを2つ作る必要があるため、性能に影響が出そう
  • コピーが重い
  • マクロ展開がライブラリを使用しているのだけれど・・・
まぁ、ダミーのライブラリを作る必要はないかもしれないのでそこは下2つは無視できるかもしれないが。

REPLでしか起きない問題なので多少以上にやる気が低いのも問題だろう・・・

No comments:

Post a Comment