MessagePack・JSONとnil

nmoshはMessagePackやJSONを読み書きできる。が、JSON(JavaScript)とS式(Scheme)には絶妙な表現力の違いが有って、なかなか難しい。

  • バイナリと文字列

MessagePackはバイナリと文字列を区別できない( https://github.com/msgpack/msgpack/issues/116 )。nmoshはR6RSなのでbytevectorとstringを別々の型として持っている。
MessagePack RPCではメソッド名の記述に文字列を使うが、これがSchemeから見た時にはbytevectorになってしまうので、単純なwriteでは人間に読み易くない。
この2つを独立した型にするかどうかは絶妙なところで、例えばGaucheの不完全文字列( http://practical-scheme.net/gauche/memo-str-j.html )のようにScheme処理系でも(故意に)文字列をバイト列としてあつかうための方法を用意しているケースもある。

  • nliと長さゼロのリスト、オブジェクト

こちらは逆のケースで、Schemeでは長さゼロのリストとnilを区別できない。JSONでは長さゼロのリスト(配列)とnil(null)を当然区別できる。MessagePackにはundefinedは無いが、nilは有る。
この違いは上のケースよりもより本質的で、再変換したときに元に戻らない可能性がある。長さゼロの配列もそれなりに使用される可能性がある。
しかも、MessagePack RPCは正常終了の通知にnullを使う(!)ので、処理系は両方のモードを備えないといけない。。シンボルをつかうという裏ワザも有るが。。
nmoshはオブジェクトをベクタに割り当てているので、長さゼロのベクタをJSON上の長さゼロのオブジェクトと見做せる。

見やすさと論理的な整合性

nmoshのMessagePack/JSONは、JSON的な配列をリストに、オブジェクト(キー/値ペアのリスト)をベクタに割り当てている。
これを逆にすべきなんじゃないかというのは常に悩んでいるポイントで、将来変えちゃうかもしれない。
JSONの規格的にはオブジェクトはunorderedだが、nmoshでは辞書(ハッシュテーブル)にはしていない。RFC 4627のJSONではキーのユニーク性はSHOULDレベルなのと、逆変換のため。もっとも、json.orgのパーサも含め、多くのパーサはキーの重複を禁止している。
このへんのJavaScriptとの連携は誰かが検討してSRFIを書いてくれると良いのだけれど。