[reactive] unsafePerformIO: is it correctly used?

Peter Verswyvelen bugfact at gmail.com
Thu Nov 20 18:06:02 EST 2008

When I was browsing the GHC documentation, I came across the following:
If the I/O computation wrapped in
side effects, then the relative order in which those side effects take place
(relative to the main I/O trunk, or other calls to
is indeterminate. You have to be careful when writing and compiling modules
that use unsafePerformIO<file:///C:/app/ghc-6.10.1/doc/libraries/base/System-IO-Unsafe.html#v%3AunsafePerformIO>

   - Use {-# NOINLINE foo #-} as a pragma on any function foo that calls
   If the call is inlined, the I/O may be performed more than once.
   - Use the compiler flag -fno-cse to prevent common sub-expression
   elimination being performed on the module, which might combine two side
   effects that were meant to be separate. A good example is using multiple
   global variables (like test in the example below).
   - Make sure that the either you switch off let-floating, or that the call
   to unsafePerformIO<file:///C:/app/ghc-6.10.1/doc/libraries/base/System-IO-Unsafe.html#v%3AunsafePerformIO>
   float outside a lambda. For example, if you say: f x = unsafePerformIO
   (newIORef []) you may get only one reference cell shared between all
   calls to f. Better would be f x = unsafePerformIO (newIORef [x]) because
   now it can't float outside the lambda.

Now in Reactive, in e.g. the internal IVar.hs module, I see

readIVar :: IVar a -> a
readIVar (IVar v) = unsafePerformIO $ readMVar v

At first sight this function is not following all the rules described above.
Could this cause problems?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/reactive/attachments/20081121/ff3f3821/attachment.htm

More information about the Reactive mailing list