RE: unsafePerformIO

But it is a fact that many of us have at least some idea of what happens "under the hood" when we use unsafePerformIO. This is also described in your paper "Stretching the storage manager: weak pointers and stable names in Haskell".
However, I for example have no idea what happens when unsafely executing something that throws exceptions, performs a forkIO, something that uses MVar's, etc.
Exceptions: an exception raised by the computation inside unsafePerformIO will be propagated to the enclosing expression, as per the normal semantics for imprecise exceptions. The exception raised by an application of unsafePerformIO may of course also be imprecise; consider 'unsafePerformIO $ (1/0 + error "foo") `seq` return ()'. The behaviour of forkIO and other side-effecting operations inside unsafePerforIO can I think be explained by the following statement: if an expression "unsafePerformIO e" has been reduced to head normal form, then all the I/O computations in e have been performed. The exact timing of the evaluation is underspecified, just as any other expression in Haskell. However, if you're using unsafePerformIO with real side effects, then I suspect that what you're doing is highly dodgy and you should find another way to do it :-) Does that help? As for sharing, we currently don't provide any guarnatees, although we should. It is currently the case that if you write a = unsafePerformIO (putStr "hello") b = unsafePerformIO (putStr "hello") and both a and b are evaluated, then you may get either one or two "hello"s on stdout. You can currently make things more deterministic by (a) adding NOINLINE pragmas for a and b, and (b) using the flag -fno-cse to disable common sub-expression elimination. Then you'll get exactly two instances of "hello" on stdout, although we won't guarantee that behaviour for ever. At some point we'll fix it so that unsafePerformIO applications are never duplicated or coalesced. If you're interested in when unsafePerformIO is "safe" to use, see: http://www.haskell.org/pipermail/glasgow-haskell-users/2002-July/003683. html (and see my followups for an alternative view). Cheers, Simon

----- Original Message -----
From: "Simon Marlow"
As for sharing, we currently don't provide any guarnatees, although we should. It is currently the case that if you write
a = unsafePerformIO (putStr "hello") b = unsafePerformIO (putStr "hello")
and both a and b are evaluated, then you may get either one or two "hello"s on stdout. You can currently make things more deterministic by (a) adding NOINLINE pragmas for a and b, and (b) using the flag -fno-cse to disable common sub-expression elimination. Then you'll get exactly two instances of "hello" on stdout, although we won't guarantee that behaviour for ever. At some point we'll fix it so that unsafePerformIO applications are never duplicated or coalesced.
Are there any (short) examples available where using of unsafePerformIO leads to unexpected behaviour, especially an example with the terms a and b from above? with best regards, David ------------- JWGU Frankfurt
participants (2)
-
David Sabel
-
Simon Marlow