[Haskell-cafe] What unsafeInterleaveIO is unsafe

Jonathan Cast jonathanccast at fastmail.fm
Sun Mar 15 17:20:55 EDT 2009


On Sun, 2009-03-15 at 22:09 +0100, Daniel Fischer wrote:
> Am Sonntag, 15. März 2009 21:56 schrieb Jonathan Cast:
> > On Sun, 2009-03-15 at 21:43 +0100, Daniel Fischer wrote:
> > > Am Sonntag, 15. März 2009 21:25 schrieb Jonathan Cast:
> > > > On Sun, 2009-03-15 at 13:02 -0700, Ryan Ingram wrote:
> > > > > 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?
> > >
> > > But not if you switch the (x <- ...) and (y <- ...) parts:
> > >
> > > main = do
> > >     r <- newIORef 0
> > >     v <- unsafeInterleaveIO $ do
> > >         writeIORef r 1
> > >         return 1
> > >     y <- readIORef r
> > >     x <- case f v of
> > >             0 -> return 0
> > >             n -> return (n - 1)
> > >     print y
> > >
> > > Now the IORef is read before the case has a chance to trigger the
> > > writing.
> >
> > But if the compiler is free to do this itself, what guarantee do I have
> > that it won't?
> >
> 
> None?
> 
> Wasn't that Ryan's point, that without the unsafeInterleaveIO, that reordering 
> wouldn't matter, but with it, it does?

Sure.  But *that point is wrong*.  Given the two programs

main0 = do
    r <- newIORef 0
    v <- unsafeInterleaveIO $ do
        writeIORef r 1
        return 1
    y <- readIORef r
    x <- case f v of
            0 -> return 0
            n -> return (n - 1)
    print y

main1 = 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

There is *no* guarantee that main0 prints 0, while main1 prints 1, as
claimed.  The compiler is in fact free to produce either output given
either program, at its option.  Since the two programs do in fact have
exactly the same set of possible implementations, they *are* equivalent.
So the ordering in fact *doesn't* matter.

jcc




More information about the Haskell-Cafe mailing list