[Haskell-cafe] dangerous inlinePerformIO in Data.Binary(?)

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Fri Jun 15 02:29:59 EDT 2007


On Thu, 2007-06-14 at 22:50 -0700, Stefan O'Rear wrote:

> > > | unsafeLiftIO :: (Buffer -> IO Buffer) -> Builder
> > > | unsafeLiftIO f =  Builder $ \ k buf -> inlinePerformIO $ do
> > > |     buf' <- f buf
> > > |     return (k buf')
> > > 
> > > which might be safe, since 'f buf' cannot float out of the lambda which
> > > binds 'buf', but still, all this stuff is inlined, something constant
> > > might get plugged in the place of buf and the result might be floated
> > > out to give us an even harder to find Heisenbug.
> > 
> > I think this is safe because of the continuation k. In the Builder
> > monoid, the continuation takes the place of the IO state token that gets
> > single threaded through everything.
> 
> That's only safe if every function which passes an initial continuation
> (runBuilder etc) is NOINLINE - exactly the sort of global requirement
> that is far too easy to break if not documented.

There is only runBuilder that passes an initial continuation so it
doesn't seem that hard. As you know, having tried to tackle the same
problem, the Builder monoid is optimised for speed rather than for
cleanliness (though it does aim for correctness).

Duncan



More information about the Haskell-Cafe mailing list