[Haskell-cafe] unsafeInterleaveST (and IO) is really unsafe [was: meaning of "referential transparency"]

Richard A. O'Keefe ok at cs.otago.ac.nz
Thu Apr 11 02:49:40 CEST 2013

On 10/04/2013, at 2:45 PM, <oleg at okmij.org> wrote:
... unsafeInterleaveST is really unsafe ...

> import Control.Monad.ST.Lazy (runST)
> import Control.Monad.ST.Lazy.Unsafe (unsafeInterleaveST)
> import Data.STRef.Lazy
> bad_ctx :: ((Bool,Bool) -> Bool) -> Bool
> bad_ctx body = body $ runST (do
>   r <- newSTRef False
>   x <- unsafeInterleaveST (writeSTRef r True >> return True)
>   y <- readSTRef r
>   return (x,y))
> t1 = bad_ctx $ \(x,y) -> x == y   -- True
> t2 = bad_ctx $ \(x,y) -> y == x   -- False

If I remember correctly, one of the Griswold systems on the
path between SNOBOL and Icon had a special feature for looking
below the language level, called "The Window into Hell". 

Derek Lowe has a list of "Things I Won't Work With".

unsafeInterleaveST has just joined my "Things I Won't Work With" list.
But since it is new to me, I don't understand what it does or *how*
it breaks this code.  Does it involve side effects being reordered in
some weird way?

I think there is a big difference between this and lazy I/O.
unsafeInterleaveST *sounds* dangerous.
Lazy I/O *sounds* safe.
And most of the alternatives (like conduits) hurt my head,
so it is really *really* tempting to stay with lazy I/O and
think I'm doing something safe.

More information about the Haskell-Cafe mailing list