R6RS における transcoded-port が binary port を close するとは?
R6RS の transcoded-port 手続きの説明で以下のような文章がある。
As a side effect, however, transcoded-port closes binary-port in a special way that allows the new textual port to continue to use the byte source or sink represented by binary-port, even though binary-port itself is closed and cannot be used by the input and output operations described in this chapter.
これの意味が分からなかったので困っていたのだが、R6RS Rationale に説明があった。
20.5 Binary and textual ports
The plethora of widely used encodings for texts makes providing textual I/O significantly more complicated than the simple model offered by R5RS.
よく使われるテキストエンコーディングの種類はとても多すぎて、R5RSが提供するようなシンプルなモデルに比べ、テキスト I/O を提供するのは複雑で難しい。
In particular, realistic textual I/O should address encodings such as UTF-16 that include a header word determining the “actual” encoding of the rest of the byte stream, stateful encodings, and textual formats such as XML, which specify the encoding in a header line.
とりわけ 現実的なテキスト I/O は、UTF-16 のようにヘッダワードに残りのバイトストリームの「実際の」エンコーディングを示すような状態を持ったエンコーディングや、XML のようにヘッダ行でエンコーディングを示すようなテキストフォーマットをうまく扱わなければならない。
Consequently, a library implementing textual I/O should support specifying an encoding upon opening a port, but should also support opening a port in “binary mode” to determine the encoding and switch to “text mode”.
そういうわけで、テキストI/O を実装するライブラリは、ポート open 時にエンコーディングを指定できるようにするべきである一方、エンコーディングを決定するために「バイナリーモード」で port を open し、その後「テキストモード」にスイッチできるようにもしなければならない。
In contrast, arbitrary switching between “binary mode” and “text mode” is difficult to support, as it may interfere with efficient buffering strategies, and because the semantics may be unclear in the case of stateful encodings.
一方、自由に「バイナリモード」と「テキストモード」をスイッチできるようにするのは難しい。効率的なバッファリング戦略の邪魔になるであろうし、状態を持ったエンコーディングのケースで意味論が不明確になる可能性があるからである。
Consequently, the (rnrs io ports (6)) library allows switching from “binary mode” to “text mode” by converting a binary port into a textual port, but not the other way around.
このような事情から、(rnrs io ports(6)) ライブラリはバイナリポートをテキストポートに変換することで「バイナリーモード」から「テキストモード」へのスイッチは許されるが、その逆は許されない。
The transcoded-port procedure closes the binary port to preclude interference between the binary port and the textual port constructed from it.
transcoded-port 手続きは、バイナリポートと、それを元に構築されたテキストポートの間の干渉を防ぐために、バイナリポートを close する。
どういうことか?
transcoded-port に binary port を与える事で textual port に変換できるのだが、元となった binary port が外で使われるとややこしいので、使えなくなるようにしましょうということ。
(import (rnrs)) (let* ([binary-port (open-bytevector-input-port #vu8(97 98 99))] [text-port (transcoded-port binary-port (make-transcoder (latin-1-codec)))]) (display (read-char text-port)) (display (read-char text-port)) (get-u8 binary-port) ;; こんなことをされたくないので、close しておく (display (read-char text-port)))
Ypsilon は既に対応済みだった。さすが。