
Jonathan Cast wrote:
On Wed, 2008-08-27 at 11:53 +0100, Adrian Hey wrote:
John Meacham wrote:
As with all design decisions, it is sometimes the right thing and sometimes the wrong one. And sometimes the most expedient. (which, occasionally, is a perfectly valid driving force behind a certain bit of coding). However, I am fully convinced it is necessary. You don't even have to look further than Haskell 98 to find a use in the Random module, and Data.Unique _depends_ on the state being global for correctness. ..and of course there's stdin, stdout. That takes some explaining.
Not really. If you don't have buffered IO, then you just say
stdin = 0 stdout = 1 stderr = 2
nonStdout = 42? I'm afraid I have no idea what your point is :-( I tried it anyway and doesn't seem to work, but that ain't so surprising as Handles aren't Nums. What needs explaining IMO is that we appear to have "global" Handles exported at the top level from System.IO, but no way for users to write their own modules that do the same for nonStdout, or even to implement getNonStdout. I think that's pretty weird and inconsistent. But perhaps you could show me how to do it with some real Haskell :-)
If you need buffered IO, you just change your IO monad* to look like:
newtype NewIO alpha = NewIO (ReaderT (Map Fd Buffer) OldIO alpha)
Of course, if you do this, you can't go mixing IO with unique values with RNG with mutable state with everything else under the sun anymore. You might actually have to declare exactly what effects you need when you give your function's type, now. Clearly, a horror we must avoid at all costs.
Indeed. If anyone thinks that's the way to go maybe Clean would be of some interest. IMHO Cleans treatment of IO and concurrency is just about the worst thing in an otherwise pretty decent language :-( Regards -- Adrian Hey