#gosh> (use scheme.eval)
#<undef>
gosh> (map module-exports (module-imports (environment '(rename (only (scheme base) + *) (+ f)))))
((+ f))
gosh> (map module-exports (module-imports (environment '(prefix (rename (only (scheme base) + *) (+ f)) %))))
(())
#renameやprefixをつけると module-exports が期待したものと違うんですが、何故ですか?
#根本的な理由は、(1)Gaucheはopen moduleを採用してるためexportされるシンボルの集合が固定ではない (2)module-exportsの実装をさぼってる、からです。ただrenameのそれはちょいと動作が怪しいですね。
#(import (prefix (foo) foo:)) とした場合、特殊な無名モジュールが作られて、そのモジュールを通してみるとfooからexportされているシンボルがあたかもfoo:がついてexportされてるように見えます。しかし、importの後でfooから新たなシンボルがexportされる可能性があるので、import時点で無名モジュールがexportすべきシンボルを全て列挙してしまうことはできません。コンパイラが束縛を探しにいった時点で動的にfooを見に行くことで、あたかもfooがexportしてる全てにfoo:がついたものをexportしてるかのように動作させています。
#module-exportsも呼ばれる度にexport setを計算するようにすれば見かけの動作と一致するんですが、今まであんまりそこが厳密に必要になるケースが少なかったのでちゃんとやってないです。
#(renameのはnegative bindingが見えちゃってるのかな? 要調査)
##あ、間違いかも。prefixだけだと中間モジュールは作らないや。renameが中間モジュールを作って、そいつがmodule-exportsにどう応答してるかだな。
#いや、前言撤回。prefixも中間モジュールを作る。そいつがfooをinheritする。シンボルを探すときにちょっと細工がある。
#なるほど、ありがとうございます。
#module-exportsが実態を正確に反映しててほしい、というユースケースがあるのなら参考にします。
#ええと、R7RSno
#まだ整理できていないんですが、R7RSのimport specから見える束縛の一覧を作りたかったんだと思います。
#確かにmodule-exportsがちゃんと機能する方が嬉しくはあるな。そう頻繁に呼ぶものでもないので真面目に計算することにしようかな。
#モジュールの継承はexportsも継承するから、特にrenameとかprefixとか使ってなくてもmodule-exportsは祖先モジュールのexportsを調べてマージしないとならない。