2009-12-12

Common Lispでの標準出力へのバイナリデータの出力

SchemeR6RSで揉めているので、Scheme Steering Committeeが何らかの成果を出すまで様子見をしつつ、Common Lispを試してみることにした。結構居心地が良い。SLIMEが便利過ぎる。

ただ、Schemeとの違いに戸惑うことも結構あって、今回は標準出力へのバイナリデータの出力について。

Schemeでは、R5RSのポートはテキストとバイナリの区別が無いので、処理系依存にはなるものの、バイナリデータを素直に書き出すことができる。R6RSでは、テキストポートとバイナリポートが定義され、standard-output-portは標準出力に対応するバイナリポートを返し、current-output-portはテキストポートを返すと決められている。R5RSと互換性を取りつつも、バイナリデータもしっかり扱えるようになっていて、R6RSはこういう所が結構上手くできていると感じる。レコードの仕様とか、とても賛成できないようなものも多いけど。

Common Lispでは、ポートではなくストリームになるわけだけど、テキストとバイナリの区別はちゃんとできる。ただ、標準出力に対応するストリームの*standard-output*が処理系依存なので、標準出力にバイナリデータを出力するポータブルな方法がない。ただ、/dev/stdoutを使ったり、処理系の独自拡張を使えば、処理自体はできたりする。

詰めが甘いというか、この辺、もっとどうにかならなかったんだろうか。パイプでデータを受け渡すやり方って、昔から割と良くあるパターンだと思うんだけども。

ちなみに、今回のきっかけは、処理系が対応してない外部文字エンコーディングのCGIでの取り扱い。変換されたバイト列を、標準出力にバイナリデータとして出力すればいいんじゃないかと思ったら、ひと工夫必要だった、という話。