
Hello Takano, Sunday, June 11, 2006, 1:18:35 PM, you wrote:
I wrote an IO library, inspired by, and partly based on, Bulat Ziganshin's Streams library. The main aim of the library is to experiment with different design choices, especially emphasizing the following:
* Many small classes * Iconv-friendly interface
The source code and documentation can be found at: http://yogimo.sakura.ne.jp/ssc/
first i considered your library as ready-to-use alternative to Streams and was discouraged. but then i understood that it is only proof-of-concept for alternative class structure and realized that for this purpose it serves very well - everything works just as it should work, every bit of Simon's critique about monolithic Stream class was taken into account
== Type structure
The library tries to assign a different class for a different concept. For example, it distinguishes read-only streams from write-only ones, and seekable streams from non-seekable ones. As a result, the library provides a small and clean interface, so it ensures more type safety, and type signatures of stream-operating functions are able to carry more information.
moreover, you've implemented this w/o duplicating functionality in read, write and read/write classes and virtually w/o speed penalty, by creating "manager" (you call it Controller) class to switch between reading and writing Port behavior
== Iconv friendliness
Although Unicode is quickly becoming popular, there are still many widely-used, character-set-specific encodings. Therefore i18n-aware applications may have to handle a locale-specific encoding, which is not statically known. Then, using an external conversion routine, such as iconv, will be virtually the only possible way to go. The library's interface intaracts well with iconv and other c runtines. This also means that adding zlib functionality can be easy, for example.
about your example of using UTF8+Latin1 encoding on one stream: it shouldn't work for using any encoding AFTER UTF8 (i don't have Unix, so i not compiled your lib and don't make actual tests). imagine that first 10 bytes in file represent 8 UTF8 chars. after decoding, these chars will be represented by 32 bytes (8 UTF-32 values). when you make sCleanup, library just can't know what those 32 bytes read from intermediate buffer correspond to 10 bytes in lower-level stream
== Performance
The library is currently not very fast. For example, typical repitition of putStr/getLine is 1.5x slower than the corresponding standard Handle operations. When you omit locking, the library performs roughly equally well to the standard Handle.
to make performance maximal, you should use INLINE pragmas, unboxed references and many other small toys of True Glasgow Inliner :) of course, you don't need to do so in proof-of-concept lib the only overhead imposed by your design by itself is to check one IOURef (unboxed variable) per each operation and even that is required only for controlled r/w streams i also specially mentioned your implementation of locking transformer. if i correctly understood, it allows to add locking even when stream is used by two transformer paths (such as UTF8+Latin1), in contrast to my library i still don't understood your whole class structure and therefore can't compare it exactly to my current design (where i splitted Stream class only to BlockStream/MemoryStream/CharStream/ByteStream with corresponding operations inside each class) and therefore can't decide whether i like to go in your direction or don't like :) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com