<div dir="ltr">I believe you are safe to do this for now with GHC.  There is some relevant discussion here [1].<div><br></div><div>[1]: <a href="http://www.haskell.org/haskellwiki/Top_level_mutable_state">http://www.haskell.org/haskellwiki/Top_level_mutable_state</a></div>
<div><br></div><div>Note that doing:</div><div><br></div><div>    <span style="font-family:arial,sans-serif;font-size:13px">{-# NOINLINE counter #-}</span></div><span style="font-family:arial,sans-serif;font-size:13px">    counter :: TVar Int</span><br style="font-family:arial,sans-serif;font-size:13px">
<span style="font-family:arial,sans-serif;font-size:13px">    counter = unsafePerformIO $ atomically $ newTVar 0</span><div><br></div><div>Is not safe [2].</div><div><br></div><div>[2]: <a href="http://hackage.haskell.org/package/stm-2.4.2/docs/Control-Concurrent-STM-TVar.html#v:newTVarIO">http://hackage.haskell.org/package/stm-2.4.2/docs/Control-Concurrent-STM-TVar.html#v:newTVarIO</a><br>
<div><br></div><div>Ryan<br><div><br></div><div><br></div></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jan 29, 2014 at 2:32 AM, Alexander Alexeev <span dir="ltr"><<a href="mailto:mail@eax.me" target="_blank">mail@eax.me</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello!<br>
<br>
Lets consider the following code:<br>
<br>
import Control.Concurrent<br>
import Control.Concurrent.STM<br>
import System.IO.Unsafe (unsafePerformIO)<br>
<br>
{-# NOINLINE counter #-}<br>
counter :: TVar Int<br>
counter = unsafePerformIO $ newTVarIO 0<br>
<br>
incCounter :: IO Int<br>
incCounter = do<br>
  r <- atomically $ do<br>
    t <- readTVar counter<br>
    let t' = t + 1<br>
    writeTVar counter t'<br>
    return t'<br>
  return r<br>
<br>
main :: IO ()<br>
main = do<br>
  n1 <- incCounter<br>
  print n1<br>
  n2 <- incCounter<br>
  print n2<br>
  n3 <- incCounter<br>
  print n3<br>
<br>
This program prints:<br>
<br>
1<br>
2<br>
3<br>
<br>
So we have a "global variable". Do I right understand that newTVarIO<br>
creates TVar and RTS memoizes it since 'counter' function is pure? If<br>
it's true, could it happen that under some circumstances memoized value<br>
will be deleted from memory? Or Haskell keeps all memoized values<br>
forever?<br>
<br>
Another issue which I'm afraid of --- would the given code be safe in<br>
multithread application? For example, is it possible to encounter a<br>
race condition if two threads will try to create a new counter in the<br>
same time?<br>
<br>
Is there any other problems which should be taken in account?<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Best regards,<br>
Alexander Alexeev<br>
<a href="http://eax.me/" target="_blank">http://eax.me/</a><br>
_______________________________________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</a><br>
</font></span></blockquote></div><br></div>