[Haskell-cafe] What unsafeInterleaveIO is unsafe
Jonathan Cast
jonathanccast at fastmail.fm
Sun Mar 15 16:25:09 EDT 2009
On Sun, 2009-03-15 at 13:02 -0700, Ryan Ingram wrote:
> unsafeInterleaveIO allows embedding side effects into a pure
> computation. This means you can potentially observe if some pure
> value has been evaluated or not; the result of your code could change
> depending how lazy/strict it is, which is very hard to predict!
>
> For example:
>
> > -- given
> > f :: Integer -> Integer
> >
> > main = do
> > r <- newIORef 0
> > v <- unsafeInterleaveIO $ do
> > writeIORef r 1
> > return 1
> > x <- case f v of
> > 0 -> return 0
> > n -> return (n - 1)
> > y <- readIORef r
> > print y
> >
> > -- a couple of examples:
> > f x = 0 -- program prints "0"
> > -- f x = x -- program prints "1"
>
> "f" is pure. But if f is nonstrict, this program prints 0, and if
> it's strict, it prints 1. The strictness of a pure function can
> change the observable behavior of your program!
Right. If the compiler feels like changing the way it implements your
program based on that factor. But `semantics' that the compiler doesn't
preserve are kind of useless...
> Furthermore, due to the monad laws, if f is total, then reordering the
> (x <- ...) and (y <- ...) parts of the program should have no effect.
> But if you switch them, the program will *always* print 0.
I'm confused. I though if f was strict, then my program *always*
printed 1?
> Also, the compiller might notice that x is never used, and that "f" is
> total. So it could just optimize out the evaluation of "f v"
> completely, at which point the program always prints 0 again; changing
> optimization settings modifies the result of the program.
>
> This is why unsafeInterleaveIO is unsafe.
Well, unsafeInterleaveIO or reasoning based on overly specific
assumptions about how things must be implemented, anyway. I'm not sure
you've narrowed it down to usafeInterleaveIO, though.
jcc
More information about the Haskell-Cafe
mailing list