GuileのR6RS対応を試す
サマリ : 簡単なスクリプトなら動くが工夫が必要
Guile 2.0がそろそろリリースされる。このリリースの目玉は世間的にはJavaScript/EmacsLispのサポートな気がするが、ice-9が標準のモジュールシステムになったことで、Guileのモジュール構文がR6RS Schemeと互換になったことにも注目したい。
Guileは(GNU標準言語なので)一応世間的に知られたScheme処理系で、そのGuileと共通で使えるモジュールが書けるようになったのは、Schemeの相互運用性という点ではそれなりに前進するように思える。
しかし、現状ではGuileにR6RSライブラリを使わせるのはそれなりに工夫が必要になる。
- .sls拡張子と.guile.sls拡張子に対応する
Guileは標準で.scmしか見にいかない。
(set! %load-extensions '(".guile.sls" ".sls" ".scm"))
のようなファイルを作って(guile-load.scmのような名前で保存し、)Guileの起動時に読ませる必要がある。
たとえば、racketのR6RS test suiteを走らせるには、
guile -l guile-load.scm -L racket/collects racket/collects/tests/r6rs/run/hashtables.sps
のようなコマンドラインになる。
ちなみに、Guileはmoshと同じくpsyntaxをexpanderに採用している。よって、importのfor指定は無視され、expand時とrun時で同じ名前空間を共有できる。
コンパイルキャッシュの採用
Guile 2.0の重要な変化として、バイトコードVMを採用したことも挙げられる。このため、Guileはmoshやypsilonのようなバイトコードキャッシュを備えている。
バイトコードキャッシュは、基本的に~/.cache/guileに配置される。(nmoshも.cache以下にキャッシュを移す予定。このディレクトリはfreedesktop標準のキャッシュディレクトリであるため。)
Guileのバイトコードキャッシュも、(pure R6RSで実装された)includeのようにimplicitなファイル依存関係が生じたときは正常に動作しないように思える。
現状の互換性
低い。特に、portと例外を使ったスクリプトは動作しないことが多い。
test | pass/fail |
---|---|
base | error(exception handling) |
bytevectors | error(datum comment) |
conditions | error(record impl) |
contrib | error(exception handling) |
control | 11 pass |
enums | 26 pass |
eval | 3 pass |
exceptions | error(get-string-n) |
hashtable | 12/249 fail(exception handling) |
io/ports | error(expand?) |
io/simple | error(unimplemented: port) |
lists | error(exception handling) |
mutable-pairs | error?(timeout) |
mutable-strings | error(exception handling) |
programs | 2 pass |
r5rs | error(exception handling) |
reader | 70 pass |
records/procedural | 21 pass |
records/syntactic | 4/53 fail |
sorting | 4 pass |
syntax-case | error(exception handling) |
unicode | 22/118 fail |
ただ、moshのbootstrapは現状のGaucheを使ったものから、時期を見てGuileを含めたR6RS Schemeへ移行するつもりなので、Guileとの互換性は今のうちからチェックしておこうと考えている。