Unsafe hGetContents

Simon Marlow marlowsd at gmail.com
Tue Oct 6 09:50:32 EDT 2009


On 06/10/2009 14:18, Nicolas Pouillard wrote:
> Excerpts from Simon Marlow's message of Tue Oct 06 14:59:06 +0200 2009:
>> On 03/10/2009 19:59, Florian Weimer wrote:
>>> * Nicolas Pouillard:
>>>
>>>> Excerpts from Florian Weimer's message of Wed Sep 16 22:17:08 +0200 2009:
>>>>> Are there any plans to get rid of hGetContents and the semi-closed
>>>>> handle state for Haskell Prime?
>>>>>
>>>>> (I call hGetContents unsafe because it adds side effects to pattern
>>>>> matching, stricly speaking invalidating most of the transformations
>>>>> which are expected to be valid in a pure language.)
>>>>
>>>> Would you consider something like [1] as an acceptable replacement?
>>>>
>>>> [1]: http://hackage.haskell.org/package/safe-lazy-io
>>>
>>> It only addresses two known issues with lazy I/O, doesn't it?  It
>>> still injects input operations into pure code not in the IO monad.
>>
>> While what you say is true, and I've complained about the same thing
>> myself in the past, it turns out to be quite difficult to demonstrate
>> the unsafety.
>>
>> Try it!  Here's the rules.
>>
>>     - write a program that gives different results when compiled with
>>       different optimisation flags only. (one exception: you're not
>>       allowed to take advantage of -fno-state-hack).
>>
>>     - Using exceptions is not allowed (they're non-determinstic).
>>
>>     - A difference caused by resources (e.g. stack overflow) doesn't
>>       count.
>>
>>     - The only "unsafe" operation you're allowed to use is hGetContents.
>>
>>     - You're allowed to use any other I/O operations, including from
>>       libraries, as long as they're not unsafe, and as long as the I/O
>>       itself is deterministic.
>>
>> The reason it's hard is that to demonstrate a difference you have to get
>> the lazy I/O to commute with some other I/O, and GHC will never do that.
>>    If you find a way to do it, then we'll probably consider it a bug in GHC.
>>
>> You can get lazy I/O to commute with other lazy I/O, and perhaps with
>> some cunning arrangement of pipes (or something) that might be a way to
>> solve the puzzle.  Good luck!
>
> Oleg's example is quite close, don't you think?
>
> URL: http://www.haskell.org/pipermail/haskell/2009-March/021064.html

Ah yes, if you have two lazy input streams both referring to the same 
underlying stream, that is enough to demonstrate a problem.  As for 
whether Oleg's example is within the rules, it depends whether you 
consider fdToHandle as "unsafe": Haskell's IO library is carefully 
designed to not run into this problem on its own.  It's normally not 
possible to get two Handles with the same FD, however 
GHC.IO.Handle.hDuplicate also lets you do this.

Cheers,
	Simon


More information about the Haskell-prime mailing list