

撃墜率高すぎ。。https://github.com/okuoku/yuni/issues

SECDVでR7RSライブラリを実装するついでに同じテストをR6RS/R7RS処理系でも走らせているけど、意外と問題が出る。yuniにはR6RSで使うためのR7RS語彙がいくつか実装されていて、そのライブラリの不具合であったり、処理系自体の不具合(や微妙な挙動)であったり様々。

というわけで、テストを足すたびに特定の処理系を外す処理をいつも入れている気がする。一応、yuniはR6RS/R7RS準拠を謳う処理系をターゲットにしているが、それでもこれだけの差が出るのが多様性の難しいところというか。。

Vicareのboolean=?のバグのように軽微なものはすぐ報告( https://github.com/marcomaggi/vicare/issues/97 )できるけど、まず一旦yuniライブラリを使わない元の処理系で再現させないといけないので、なかなかバグ報告を処理できないでいる。

意外なのは、MIT/GNU Schemeのテスト通過率が良いこと。R7RSの挙動とMIT Schemeの挙動がよく一致していると言える。逆にGambitはread-stringがR7RSのそれとは別物だったり、peek-charはちゃんとあるのにpeek-u8を実現する方法が無い等R7RSにしようとすると苦労する(している)。

というわけで、portの手続きを一通りほぼ実装した。これで残るはreader/writerだけ！もう適当にやっつけて、超おもしろそうなヒープの実装に早く進みたい。。

portの実装用超適当オブジェクトシステム

R7RS Schemeでのportにはおおざっぱに言って、

bytevectorと入出力するポート

stringと入出力するポート

ファイルとテキスト入出力するポート

ファイルとバイナリ入出力するポート

の4種類あり、例えばclose-portのようにこれら4種全てをサポートする必要がある手続きもあれば、write-stringのようにテキスト出力ポートだけしかサポートしなくて良い手続きも有る。

こういうものを実装するのに向いているのはオブジェクト指向な言語によくある機構(interfaceとかclassとか)だが、R7RS Smallの標準にはCLOSのようなオブジェクトシステムは当然存在しないため、適当にお茶を濁していく方向となる。

今回実装したランタイムシステムでは、

ポートは make-yuniport 手続きに query 手続きを渡して生成する

query手続きはポートがサポートする必要のあるメソッドを内包する(いわゆるmessage passingの一種)

ポートの状態は全部クロージャに含める。超もったいない。

つまり、ファイルを開くたびに、writeとかreadのためのクロージャが毎回確保される。もったいない。

効率の面の問題は、たとえば、真面目なオブジェクトシステムを実装して解決する方向も考えられるが、ちょっとそこまでする意義があるかどうかは読み切れていない。どうせ非同期I/OとかリストI/Oが無い段階でSchemeのポートI/Oを真面目に使う機会はあんまり無いし、ここはデバッグ用と割り切って単純に実装する方向にした。逆に言うとデバッグ用機能としては重要なので安全確実な動作の方が優先度が高い。

query手続きは先程のポート種別毎に実装される(バッファ/ファイル x テキスト/バイナリ x 入力/出力 = 2x2x2 = 8種類)。

で、これらのqueryを受けとるmake-yuniportが

にある。

make-yuniportは事前にquery手続きを23回起動し、確保したベクタ(simple-struct)に結果をキャッシュする。どうせ使わないものも多いので、ここはon-demandにやっても良いかもしれない。

R7RS Smallにはハッシュテーブルすら無いため、単純にmessage passingを実装するとクエリのたびにO(N)の探索が入ることになってしまう。このため、基本的にはベクタに結果を開き、O(1)で問合せができるように配慮している。

ファイル入力ポートはバッファリングを実装していて、このバッファリングには文字列入力ポートやbytevector入力ポートを使用している。もう一段抽象化して実際のport手続きを使わないで済ませれば良いんだろうけど考えている時間が無い。

今回"テキストファイル用のread手続きの実装"とか"close処理の実装"といったport関連の処理は全てopen手続きの内部に実装されたクロージャということにした。なので、表面的にはportの処理はopenしか実装していないように見える。個人的には、こういう適当な書き方を許容できるのがSchemeの言語コアとしての強さなのかなという気がしている。