I Hate IO
Ashley Yakeley
ashley@semantic.org
Fri, 10 Aug 2001 18:31:24 -0700
At 2001-08-10 06:26, Simon Marlow wrote:
>There's lots of useful shared functionality between file I/O and socket
>I/O. For example: buffering/flushing and lazy I/O (getContents) are
>shared for files and sockets in GHC, I wouldn't want to have to provide
>N separate implementations of these things for the various different
>types of streams and files.
I can only tell you what's useful for me as an API user. Since there are
peculiar little differences between different kinds of sockets, my ideal
would be every type of socket to have its own API functions, and then
common patterns brought together with classes.
But at the very least, separate out files from sockets. I'm really not
sure why files have a "file pointer" stream-based API at all. It seems
very forced to me, but I guess everyone is so used to it from C/Unix etc.
that it seems natural.
...
>Does doing I/O in anything other than the IO monad make sense?
Probably not. But Sources and Sinks are useful general-purpose patterns.
>Why isn't writeEnd the same as close?
On a TCP connection, one can still receive data after sending an end. My
"close" is intended to be the last thing done with the connection as an
object destructor: if called before sending and receiving end, it would
simply forcibly close the connection.
>Is there anything that is always a Source but not a Sink (or vice
>versa)?
Oh yes, lots of things. Standard input/output/error for instance. One
might write code that did something like pipe from a Source to a Sink,
and then one might want a Source constructed from a constant array. Or
something. Stream-based encoding algorithms such as UTF-8 might make use
of them:
encodeUTF8:: SourceChar -> SourceWord8
etc.
> Why separate these two classes?
I think they are cleanly conceptually separable. I don't see a loss: by
making TCPSocket an instance of both, the API user still has only one
object to deal with.
--
Ashley Yakeley, Seattle WA