Let's start Scheme

2015-02-24

カスタムポート

R6RSにはカスタムポートという機能があるのは十分に知られていることだと思う。個人的にかなり使っているし非常に便利な機能だと思う。ただ、使っていると不満も出る。例えばカスタムポート自体をストレージとして使うことはできないし、port?とそれに準ずる手続きしかないため全く別のカスタムポートでも識別することができないという点である。

最初の問題は、例えばこのカスタムポートを使ってSRFI-6(open-output-stringget-output-string)を実装することはできない。バッファに溜め込んで返すようなポートをカスタムポートの機能を使って作成する場合は、open-string-output-portのような形にする以外にないのである。

次の問題は、幅があるのであるが、例えばポートがgzipポートなのかbzipポートなのかで処理を切り替えたい場合があるかもしれない。しかしながら、そのような判別を行うことはできないので、ポートを開く側で何とかするしかない。それが正しいといえばそうなんだけど、この例なら、gzipポートのときはヘッダ情報がほしいとかそういうこともできないので割りと不便なのである。あくまでポートはバイナリもしくは文字のI/Oのみに特化したもので、それ以外の処理は真面目にバイナリを扱えという位置づけともいえなくはないのだが、多段にポートをかませてフィルタをかけたいというのは割りとよくある使用例な気がしないでもない。(個人的によくやるので)

例えばGaucheにはvportという仕組みがあり、ポート自体を特殊化することができる。最近、本当につい最近なのだが、この仕組みの上にR6RSのカスタムポートを乗せた方がよかったのではないかなぁと思い始めてきた。90%くらいは現状の仕組みで問題ないのだが、10%くらい不満がでる。その10%は上記で述べた問題が主であるのだが。

問題になるのはクラス階層だろう。入力と出力、バイナリと文字という基本のクラスがありそこからファイル、バイトベクタ、文字列という感じに派生する。職業Javaプログラマになって10年以上経つのだが、こいつらを綺麗に階層化できるほどのオブジェクト指向能力がないというのが問題だろう。(一番上をインターフェースにしてとかでもいいんだけど、それはそれでなぁ。)

ちょっとポート周りのコードを見直してみたのだが、これを書き直すのはかなり大掛かりな変更になりそうな雰囲気があるのでかなり悩みものである。10%のためにこれをやるのかという話でもある。どうしたものかな。

No comments:

Post a Comment