
Hello, Ben Rudiak-Gould wrote:
... I would say that the law holds in one direction and not the other. It's safe to replace
do x <- readSTRef r y <- readSTRef r
with
do x <- readSTRef r let y = x
but not the other way around.
How can things be equal the one way and not the other? I must be misunderstanding what you are saying... As my little program showed these two pieces of code are not the same, so they cannot be arbitrarily replaced anywhere in the program. In the previous email I was trying to exaplin that I think they are the same as long as they occur in the context of runST. Of course there are many other contexts where the two are equivalent... The important thing is that there is a context that can tell them apart, and so they are not the same.
The semantics for concurrency don't guarantee that a task switch will /never/ happen between two calls of readIORef, but they don't guarantee that a task switch will /ever/ happen, either, so relying on your sample application terminating is non-portable. Therefore optimizing it in such a way that it never terminates is safe.
My example had nothing to do with non-termination. It illustrated that with the one piece of code, a boolean value in the program will be always True, while with the other it could become False (this is when the program stopped, but you cold of course do other things too). Thus, depending on which piece of code you use your program could have a completely different behaviour, and so the law I was talking about does not hold. What concurrency semantics are you reffering to? GHC provides preemtive concurrency, Hugs provides non-preemptive concurrency. The two are quite different. I was talking about GHC, as I think this is the kind of concurrency people often use. Cooperative concurency is also useful sometimes, but it is quite a different beast. -Iavor