週刊mosh - SLIME対応開始 / MessagePack対応 / r7rs 実装のポイント

moshは裏でこっそり拡張を続けているところ。0.2.8も計画しないといけないんだけど。。

修正されたバグ

bytevector-output-portが、"ポートに溜め込んだbytevectorの長さ"をリセットしていない不具合。これはMessagePackのシリアライザを書く過程で見つけた。

SLIME対応 / Slimv

nmoshのSLIME対応を開始。SLIMEはemacs上に実装されたLispの対話的デバッガ。
といっても個人的にはvimに実装されたslimvへの対応を目指す。現状ではREPLだけが実装されている。Backtraceはnmoshでないとscheme側からアクセスできないのでnmosh専用になる見込。
SWANK(SLIMEサーバ)はnmoshのアプレット機能を使って、

nmosh -T swank

のようにして起動させることができる。現在はmoshのSocketを使っているが、そのうちnmoshの非同期IOに切り替えて、動作中のプログラムを覗けるようにする予定。

slimvにはpareditのvim版が含まれていて、これが絶妙に便利。ただ、R6RSのように1つのトップレベル式が非常に長大になる環境では異常に重くなるので、s:IsBalancedは常に真を返すように修正して、,tコマンドで手動のトグルができるように修正している。
ちなみに本家paredit( http://www.emacswiki.org/emacs/ParEdit )の人はVisualStudio移植を要求されたらしい。うーむ 使ってみたい。

My new manager has asked me to port paredit to Visual Studio so that we can use it in-house,

ParEditの機能はcurses版のREPLに入れられないかと検討中。

MessagePack対応

Pure Schemeで実装したMessagePackのシリアライザ/デシリアライザを追加(yuni binary codec msgpack)。本来はC版をFFIで使おうと思ったけど、MessagePackのC実装はC99を前提にしているのでかなり移植性が悪く、結局自前で作ってしまった。
よく他の言語のユーザから指摘されるように、Schemeでは長さゼロのリストとnil(空リスト)を区別できない。というわけで、一旦MessagePackにシリアライズすると元には戻らないことがあるのに注意。
Schemeデータとの対応は既存のJSONライブラリに合わせた。つまり、Arrayがリストで、Mapがvectorになる。
さらに、(nmosh net msgpack)として、MessagePackをPDUとして用いたTCPサーバを簡単に書けるライブラリを追加した。これはnmoshの非同期I/Oに依存しているのでnmosh専用だけど、単純なcallbackをいくつか提供するだけですぐにサーバを作ることができて便利。MessagePackはRubyJavaといったほかの言語にも移植されているので、これらの言語と簡単に通信する手段として使えないかと考えている。
将来的にはMessagePack/RPCにも対応したいところ...。

R7RS実装のポイント

r7rs-bridgeは除算を除いて大体実装が完了した。この実装の課程でchibi-schemeの実装漏れを見つけたりする等、alternativeなR7RSとしての役割を果たし始めている。
(nmosh)ライブラリは早ければ0.2.8にR7RS bridgeを用いたR7RS small + shortenのようないくつかのnmosh構文になる予定。つまり、syntax-caseやidentifier-syntaxは無くなり、recordはSRFI-9になる。もちろん、(rnrs)を明示的にimportすれば従来のR6RSも使用可能。
(第三次投票の結果( http://d.hatena.ne.jp/mjt/20110711/p1 )、R7RSも補助キーワードはboundになったので、R6RSライブラリをR7RSプログラムにimportして使ったり、その逆も可能になっている。)
r7rs-bridgeでは、open-bytevector-output-portのようなbufferd portをweakポインタを使って実装している。R7RSではSRFI-6風の多値を使わないバッファポートのAPIにしているので、portオブジェクトと、結果問い合わせ手続きが完全に分離したR6RSでは簡単には実装できない。
moshの場合、文字列portに関してはSRFI-6風のAPIを持っているので、bytevectorに対しても同様の対応を行えば、回りくどい方法で実装する必要はなくなる。