2012-09-01

exportされた変数

一つ前の記事に言及していた記事の著者さんからコメントが付いてた。っで、自分の書いたコメントに疑問が(ぉぃ
set!で変更可能となると、「取り扱い注意」のラベルが必要かもしれませんが。
よく考えてみると、Sagittariusでは以下のようなことができる。
(library (test)
    (export variable)
    (import (rnrs))
  (define variable 1))

(import (test))
(set! variable 2)
(print variable)
#|
;; Output
2
|#
これはR6RS的にはエラーにならないとまずい。記憶が正しかったら、R7RS的にもエラーだったはず。
Sagittariusではデフォルト(というか、現状だと必ず)「取り扱い注意」のラベルが要ることになる。直すかなぁ。変更できた方が便利だろうかと思ったんだけど、変更されない方が便利だよなぁ。

でも、Ypsilonでも#!r6rsをつけないとエラーにならないなぁ。 どうしよう?

とりあえず、実行時エラーにするようにしてみた。ただ、これコンパイルエラーにした方がいろいろ嬉しいのだが、それをやると非常に不便になる。以下が不便になる例。
(library (test)
    (export variable)
    (import (rnrs))
  (define variable 1)
  )
(library (test2)
    (export variable)
    (import (rnrs) (test))
  (define variable 'hoge) ; ここ
  (define (aa) (set! variable 2))
  )
R6RSやR7RS的にはコメントで示している部分はエラーにならないといけないんだけど、それやるとSRFIとかでガチンコでぶつかっている手続きがエラーになる。(removeとか、振る舞いまで違うから再定義せざるを得ない)。
実はコンパイル時に再定義を不可にすることは出来るんだけど、やるといろんな場所に修正が走るのでやりたくない。テストカバレッジが100%ならまだ楽なんだろうけど、残念ながらそうでもないのが更にやりたくなさを加速させている。
Scheme的にどちらが正しいかは置いておいて、ユーザ的にはどっちの方が嬉しいのか気になるところ。
僕は再定義可能に1票。(これも揺れるところだけど・・・)

2 comments:

shiro said...

R6RSのimportはidentifierをそのまま持ち込むので、再定義はそのidentifierの意味を変えてしまうためにエラーとされてるのでしょう。

Gaucheのimportセマンティクスは「束縛の可視性」を持ち込むので、再定義すると単にそれまで見えていた(importしていた)束縛がシャドウされるだけです。同名のidentifierをexportしているライブラリを順にimportしても、コンフリクトせずに後からimportした方がシャドウします。これはルーズに開発している時は便利なのですが、可視性がimportの順序に依存するとか、色々不都合もあります。

kei said...

R6RSのimportはそれはそれで便利だと思うんですけど、僕はGaucheチックな解決の仕方を選択したみたいで、ばっちりimport順に依存しています。

それのせいで(おかげで?)あんまり再定義に抵抗がなかったのですが、それでいいのかなぁ?と疑問に思えてきたのもあるので、いろんな意見が聞きたいなぁと思った次第です。

Post a Comment