週刊nmosh - issue管理行き

yuniの移植過程で出た問題をGitHubのissueに入れていくことに。

現時点で12件有るこの前途多難ぶり。。これからFFIを入れはじめたらどうなってしまうことか。。
例えば https://github.com/okuoku/yuni/issues/1 とか https://github.com/okuoku/yuni/issues/2 のように他所の処理系の問題であってもyuni側にも起票し、対向するバグ票にリンクする形で。
タグはかなり積極的に使用している:

GitHubのissuesは他所にエクスポートしたり他のシステムとの連携が柔軟にできないので、あんまり積極的に使うものでもないような気もする。一種のベンダロックインとも言える。

今週のissue

というわけで起票したもの全部を挙げると大変なことになるので適当にピックアップ。

Chickenはr7rs eggでR7RSのライブラリ構文をサポートしているものの、... とか _ のようなSchemeで使用される補助構文がどこのライブラリにも無い。このため、yuniのように(scheme base)をエイリアスするライブラリを書くことができなくなってしまう。
yuniではR7RS標準の補助構文はリネームしてはいけないというローカルルールを設け、chickenのような実装の場合はexportから外すことで対応する。(GaucheSagittariusでキーワード風のシンボルをexportから外すのと同様。)

もっと深刻なのは、Chickenのexpanderはモジュールで定義した構文を明示的なexportなしではモジュールの外で展開させられない点。これはGaucheに起票した問題 ( https://github.com/shirok/Gauche/issues/42 )の拡張で、構文のスコープがかなり制約されることになる。
マクロを分割して定義したいだけならば、(ネストは深くなるものの)let-syntaxを使った記述に置き換えることで多くの場合は対処できる。しかし、issueに書いたコードのように、"define(-syntax)で導入する束縛のbody部分で使うマクロ"をマクロで導入することはlet-syntaxではできない。
原理的には、全てをexplicit-renamingマクロで書き直し、毎回全ての中間マクロを(gensymして)インスタンシエートすれば良い。ただyuniはsyntax-caseな処理系と実装を共有している都合上、syntax-rulesの枠でこれが書けないと困ってしまう。
これをサポートすることにはトレードオフが有る; expand済みのライブラリをキャッシュするようなケースでは、exportしていないものも含めて全てのマクロ展開コードを保持する必要が生じる。Chickenのようなセマンティクスは、明示的にエクスポートされていない構文の展開コードは保持する必要が無い。これを良くサポートするには、nmoshのようにexplicit phasingな処理系とする必要が有る。

R5RS / R7RS枠でライブラリを構築することの難しさ

というわけで、yuniを始めてみてわかったのは、マクロを多用しつつR6RS / R7RSハイブリッドなライブラリを構築するのは思いの外難しいという点。(SLIB以外の)他所のSchemeライブラリがあまり複数の処理系に対応していないのも頷ける話というところか。。

例えば、R6RS処理系ではsyntax-rulesのリテラルに _ を使えない。しかし、chibi-schemeでは普通に使えてしまう。SRFI-46なsyntax-rulesは ... を置き換えることができるが _ を置き換えることはできないので、事実上 _ を含む構文をポータブルに記述する方法が無くなってしまう(原理的には _ をlet-syntaxで差し替えることで記述できるが...)。
なんともバッドノウハウ的だが、Schemeライブラリをポータブルにするには可能な限りマクロを避けた方が良いのかもしれない。

今週やること

C言語stub生成の続き。
API記述のためのIDLを用意するよりも、個々のAPI記述オブジェクトを構築するためのAPIをちゃんと準備するほうがずっと必要そうなので、そこから。
これはAPI"セット"毎に異なるIDLを使いたい需要が有るため。例えば、Win32ならではの追加メタデータ(ANSI←→UnicodeAPI対応等)が有り、それらを全てGenericに吸収するIDLを設計するのは難しい。APIセット特化IDL→汎用IDLへS式レベルで変換することも考えられるが、最初からC言語バインディングを用意することを想定してAPIを切ってしまう。