文字列ポートとトランスコーダ

Larceny という R6RS 処理系があり、その公式サイトにはいくつかの処理系に対してベンチマークをとった結果が掲載されている。

http://www.larcenists.org/benchmarksGenuineR6Linux.html

この表をよくみると read0 というベンチマークにおいては mosh の結果が省略されていることに気付くだろう。 実際に mosh で実行してみると、テストに失敗したという旨のエラーが大量に表示される。 read0 は文字列ポートのテストケースをベンチマークに流用したものらしく、そのテストに失敗している。

では mosh は規格に不適合な部分があるのだろうかと調査したところ、テストの方が誤りであることがわかった。 open-string-input-port で開いた文字列ポートには transcoder が関連付けられても関連付けられなくてもよく、関連付けられる場合にしても transcoder は処理系依存であるとされているので、実装ごとの多様性が許されるのだ。

eol-style が none 以外の transcoder が文字列ポートに関連付けられるという想定でテストケースを作っているために read0 は失敗していたわけだ。

処理系ごとの違いが出る短いコードを用意していくつかの処理系で試してみた。

#!r6rs
(import (rnrs))
(display
 (number->string
  (char->integer
   (string-ref (get-datum (open-string-input-port "\"\x85;\"")) 0))
  16))

それぞれの実行結果はこうなった。

$ mosh test.scm
85
$ petite --program test.scm
A
$ sash test.scm
a
$ larceny -r6rs -program test.scm
a
$ Racket test.scm
a
$ ypsilon -6 test.scm
a
$ IronScheme.Console32-v4 /nologo test.scm
85
$ guile -q test.scm
85

Scheme という言語にとっては枝葉のことであるし、どうでも良いと言えばどうでも良いのだが、 R6RS では Unicode を採用することにした以上、全面的に未定義というわけにもいかなかったのだろう。

Document ID: 4f061eec50051ff472bf3594be9b6cb3