
http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%...
GHC note: a Handle will be automatically closed when the garbage collector detects that it has become unreferenced by the program. However, relying on this behaviour is not generally recommended: the garbage collector is unpredictable. If possible, use explicit an explicit hClose to close Handles when they are no longer required. GHC does not currently attempt to free up file descriptors when they have run out, it is your responsibility to ensure that this doesn't happen.
this issue has been discussed in the past, and i consider it a bug if the memory manager tells me to handle memory myself;-) so i do hope that this infelicity will be removed in the future (run out of file descriptors -> run a garbage collection and try again, before giving up entirely).
Are we at the point that we should consider adding some documentation how to deal with this issue? And are the recommendations to either use strict IO (should we have a package for System.IO.Strict??), or via strictness on the consumer of the data.
i'm all for having a readFileNow, right next to readFile. apart from that, it might be sufficient to mention explicitly, in the lazy i/o docs, that - lazy i/o and strict i/o are separate approaches to i/o - lazy i/o is more abstract, strict i/o gives better control of resources - mixing lazy and strict i/o is to be approached with special attention, because the strict i/o exposes features that are assumed to be hidden when using lazy i/o (should it be asynchronous vs synchronous i/o, instead of lazy vs strict?) as for the specific issue at hand: i've seen software with thick folders of well-written manuals explaining all the intricacies of using said software. and i've seen software which was so obvious to use that it needed hardly any printed manuals. guess which one i prefer?-) in good old Hugs, for instance, we find in function newHandle in src/iomonad.c http://cvs.haskell.org/cgi-bin/cvsweb.cgi/hugs98/src/iomonad.c?rev=1.104;con... /* return a free Handle or throw an IOError */ /* Search for unused handle*/ /* If at first we don't */ /* succeed, garbage collect*/ /* and try again ... */ /* ... before we give up */ so, instead of documenting limitations and workarounds, this issue should be fixed in GHC as well. in the meantime, the existing documentation of the GHC issue with handles is not easy to notice because readFile does not even mention handles, and their docs are in System.IO, not in Prelude. readFile refers to getContents, which refers to hGetContents stdin, which explains when handles are semi-closed and closed, but doesn't mention the implications discussed in the Handle docs. my suggestion would be that all operations that might leak handles simply ought to have their docs include a direct link to the Handle docs, as in "see notes on possible file handle leakage". perhaps the Handle docs are also the right place for the notes on lazy vs strict i/o, with appriate links to that section ("see notes on lazy vs strict i/o")? claus