[reactive] unsafePerformIO: is it correctly used?

Conal Elliott conal at conal.net
Fri Nov 21 02:22:16 EST 2008

Hi Peter,

I'm glad to see you're getting into the Reactive code!

As a complement to Luke's answer:

I think readIVar is an exception to the usual guidelines below.  The point
of the IVar type is that it can get written *at most once*, so any read will
yield the same value.  It doesn't matter in this case whether the readMVar
computation is duplicated.  It always has to yield the same result, namely
the only value that has been or will be written to the MVar, or bottom if no
value ever gets written.  As Luke mentioned, the IVar interface does not
allow takeMVar to be called, except via readMVar, which replaces the value
after reading.

  - Conal

2008/11/20 Peter Verswyvelen <bugfact at gmail.com>

> When I was browsing the GHC documentation, I came across the following:
> If the I/O computation wrapped in unsafePerformIO 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 unsafePerformIO) is indeterminate.
> You have to be careful when writing and compiling modules that use
> unsafePerformIO:
>    - Use {-# NOINLINE foo #-} as a pragma on any function foo that calls
>    unsafePerformIO. 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 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
> _______________________________________________
> Reactive mailing list
> Reactive at haskell.org
> http://www.haskell.org/mailman/listinfo/reactive
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/reactive/attachments/20081120/1782e723/attachment-0001.htm

More information about the Reactive mailing list