
When I was browsing the GHC documentation, I came across the following: If the I/O computation wrapped in unsafePerformIOfile:///C:/app/ghc-6.10.1/doc/libraries/base/System-IO-Unsafe.html#v%3Aunsaf... performs side effects, then the relative order in which those side effects take place (relative to the main I/O trunk, or other calls to unsafePerformIOfile:///C:/app/ghc-6.10.1/doc/libraries/base/System-IO-Unsafe.html#v%3Aunsaf...) is indeterminate. You have to be careful when writing and compiling modules that use unsafePerformIOfile:///C:/app/ghc-6.10.1/doc/libraries/base/System-IO-Unsafe.html#v%3Aunsaf... : - Use {-# NOINLINE foo #-} as a pragma on any function foo that calls unsafePerformIOfile:///C:/app/ghc-6.10.1/doc/libraries/base/System-IO-Unsafe.html#v%3Aunsaf.... 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 unsafePerformIOfile:///C:/app/ghc-6.10.1/doc/libraries/base/System-IO-Unsafe.html#v%3Aunsaf... cannot 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? Cheers, Peter