I Hate IO
Ashley Yakeley
ashley@semantic.org
Thu, 9 Aug 2001 02:06:46 -0700
1. A file is not a stream. It really isn't anything like a stream. Sure,
you can _make_ a stream based on a file but that's a different thing. A
file is a list (ignoring for the moment meta-information), accessible at
any point. By contrast, streams access either incoming or outgoing
entities, optionally with "end of stream" support. For incoming, one may
'skip' but not 'seek'. For outgoing, one may send a series of predefined
'zero' values. Call that "seek" if you want, I don't.
2. A file is not made of "Char"s. A file is made of octets ("bytes"),
i.e. Word8s. What is a "Char" anyway? Sometimes it's a seven- or
eight-bit quantity with a _vague_ implication of interpretation as
textual character; sometimes it's a 16-, 20.087- or 31-bit quantity with
a much stronger implication of interpretation as textual character
(strictly, Unicode "codepoint"). Is an ASCII 'r' the same as an EBCDIC
'r'? Or is an ASCII code 57 the same as an EBCDIC code 57?
As for streams, mostly they are streams of octets. But of course streams
of anything might be useful.
3. Output streams ("sinks") are different from input streams ("sources").
That POSIX entity known as "standard output" is a sink of octets. A
"bi-directional" stream such as a TCP connection is nothing but a source
and a sink considered together. Indeed, for TCP it's possible to send
"end of [outgoing] stream" without affecting the incoming stream. This is
rather different from a contrived "file-access"-type stream, where
reading and writing are operations affect each other.
There is no such thing as "I/O" unless, as in Haskell, one means _all_
imperative action. There are various entities out in the world accessible
in a variety of different ways. Sources, sinks, lists, etc. are but some
of the models useful for accessing them.
--
Ashley Yakeley, Seattle WA