RE: [Haskell] strictness of putChar: report incomplete?
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
On Wed, Oct 05, 2005 at 03:22:29PM +0100, Simon Marlow wrote:
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.
What's wrong with identifying them? You're not expecting the monad laws to hold, are you?
Am Mittwoch, 5. Oktober 2005 16:22 schrieb Simon Marlow:
[...]
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.
I think, seq should be a method of a type class. Then we could forbid applying seq to a function, we could forbid applying seq to an IO expression and we could forbid applying seq to expressions of any type with hidden implementation for which we don't want to provide bottom tests.
Cheers, Simon
Best wishes, Wolfgang
Wolfgang Jeltsch wrote:
Am Mittwoch, 5. Oktober 2005 16:22 schrieb Simon Marlow:
[...]
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.
I think, seq should be a method of a type class. Then we could forbid applying seq to a function, we could forbid applying seq to an IO expression and we could forbid applying seq to expressions of any type with hidden implementation for which we don't want to provide bottom tests.
I agree with you. And that is how it used to be, but then some people didn't think that was convenient enough so now we are stuck with a seq that (IMHO) stinks. :) -- Lennart
Am Mittwoch, 5. Oktober 2005 16:22 schrieb Simon Marlow:
[...]
Basically anything for which the report doesn't give the full code, except of course primitives which usually must be strict.
Why must primitives be strict? I wouldn't consider putChar undefined an undefined action. In my opinion, the undefinedness should only come into play when putChar undefined is executed.
[...]
Best wishes, Wolfgang
participants (4)
-
Lennart Augustsson -
Ross Paterson -
Simon Marlow -
Wolfgang Jeltsch