[Haskell] strictness of putChar: report incomplete?

Simon Marlow simonmar at microsoft.com
Wed Oct 5 10:22:29 EDT 2005


On 04 October 2005 14:16, Duncan Coutts wrote:

> On Tue, 2005-10-04 at 13:46 +0100, Malcolm Wallace wrote:
>> I wrote:
>> 
>>>> ghc:
>>>> putChar _|_ -> _|_
>>>> 
>>>> hugs:
>>>> putChar _|_ -> valid IO ()
>>> 
>>> I think it comes down to buffering behaviour doesn't it?
>> 
>> Having reviewed the IRC logs, I see I was talking nonsense.
>> 
>> You want to be able to store a closure for (putChar undefined) in a
>> data structure, which seems like a perfectly reasonable thing to do.
>> Provided the IO action is never actually run (after being retrieved
>> from the data structure), the program really ought not to crash.
>> 
>> I see that nhc98 and hbc agree with Hugs on this behaviour, so ghc
>> _must_ be wrong.  :-)
> 
> Looking at GHC's library code we see that it is indeed forcing the
> char early:
> 
> hPutChar :: Handle -> Char -> IO ()
> hPutChar handle c =
>     c `seq` do
>     ...

Fixed.  However, I have a hunch that there are a *lot* of library
functions whose strictness isn't completely specified by the report.
Basically anything for which the report doesn't give the full code,
except of course primitives which usually must be strict.  This is only
a hunch - I haven't actually gone looking for any.  I suspect we get
away with it most of the time because the desired strictness is
"obvious" and/or the compilers all agree.  Arguably, nothing returning
IO should ever be strict, but you only have to use pattern matching in
the implementation to violate that rule.

Also, GHC's optimiser currently treats (_|_ :: IO a) and (do _|_; return
()) as interchangeable, which is naughty, and people have occasionally
noticed, but the benefits can sometimes be huge.  It is this distinction
that makes it hard to optimise IO code in a Haskell compiler, though.

Cheers,
	Simon


More information about the Haskell mailing list