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