[Haskell-cafe] Lazy IO and closing of file handles

Claus Reinke claus.reinke at talk21.com
Thu Mar 15 10:30:57 EDT 2007

>> http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-IO.html#t%3AHandle
>>    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

    /* 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")?


More information about the Haskell-Cafe mailing list