[Haskell-cafe] IO and State

Iavor S. Diatchki diatchki at cse.ogi.edu
Wed Nov 10 13:35:56 EST 2004

Concurrency in Haskell (technically GHC) is much like concurrency in 
other languages,
in that you fork off threads and do stuff with them, etc. 
I think you are perhaps thinking of another kind of concurrency, where 
different redexes in
a term are evaluted simultaneously?  Here is an example to illustrate 
what I was talking about
(the point about stToIO making that one law unsafe)

 > import Control.Monad.ST
 > import Data.STRef
 > import Control.Concurrent
 > import Control.Monad(when)

 > reader     :: STRef r Int -> ST r ()
 > reader r    = do x <- readSTRef r
                   y <- readSTRef r
                   when (x == y) (reader r)

 > writer     :: Int -> STRef r Int -> ST r ()
 > writer n r  = do writeSTRef r n
                   writer (n+1) r

 > main       :: IO ()
 > main        = do r <- stToIO (newSTRef 0)
                   forkIO (stToIO (writer 1 r))
                   stToIO (reader r)

In GHC the whole program stops when the main thread exits.
So if the law I was talking about holds, this program should
never terminate, as it will forever loop in 'reader'.
However since there is a concurrent thread running that can modify
the state, if 'reader' is interrupted between the two readSTRefs
we will get different values for 'x' and 'y' and 'reader' will stop.
I tried that in GHC and it stops after a little while, so the law does 
not hold.

What is interesting is that I think the law does hold if
we execute an ST computation using runST, so at least in principle
GHC could perform this optimiziation in such situations.
I think the law holds then, as I think no reference can escape to 
concurrent threads,
as if they did their region parameter would become "RealWorld", and so 
the computation
could not be runSTed.


Graham Klyne wrote:

> At 10:38 08/11/04 -0800, Iavor S. Diatchki wrote:
>> ... Now the above law already doesn't hold when all GHC extensions 
>> are used,
>> as when concurrency is present we cannot assume that nobody modified 
>> the state concurrently.
>> As a result all pointers in GHC probably behave as if they were 
>> "volatile", which is not very nice.
> Eek!  I find this most worrisome.  And I'm not sure that I agree.
> I thought that part of the reason for having a monad that it was 
> threaded in a useful way through the path of a *single* computation 
> (expression evaluation).  If concurrent activities can change that, 
> then I sense that they're breaking something quite fundamental in the 
> way Haskell should work.
> e.g. in a sequence like:
>   v :: SomeMonad
>   v = do { e1 ; e2 ; e3 }
> Then I think that exactly the monad created by e1 is passed to e2, and 
> the result of e2 passed to e3, without any visible external 
> interference under any circumstance.  Concurrency, as I understand it 
> should apply to Haskell, would allow different elements of that 
> computation to be performed in different threads/processes, but the 
> overall result of the computation should not be changeable.  Put 
> another way, the graph reduction model for evaluating a Haskell 
> program should not change, just the mechanics actual processes (or 
> processors) actually perform the reduction steps.
> Or am I really overlooking something here?
> #g
> ------------
> Graham Klyne
> For email:
> http://www.ninebynine.org/#Contact

More information about the Haskell-Cafe mailing list