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