
#13615: Nondeterminism in ‘pure’ function w/ parallel evaluation & memo combinators -------------------------------------+------------------------------------- Reporter: pacak | Owner: bgamari Type: bug | Status: new Priority: highest | Milestone: 8.2.1 Component: Compiler | Version: 7.10.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Incorrect result | Unknown/Multiple at runtime | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by andrewthad): pacak, it should in general be safe to duplicate an ST computation on multiple threads. For IO, it's a problem because mutable variables can come from outside of the IO computation. Something like `unsafeDupablePerformIO (modifyIORef ...)` is bad because for this reason. But, with ST, variables cannot escape the scope of the computation, so it should be safe. There is no way to write the ST equivalent of the expression I just gave. You would instead have to write: `runST (do {r <- newSTRef 5; modifySTRef r ...;})`, but this should be safe to duplicate, since each thread ends up with its own STRef (no sharing of the reference across threads). Also worth mentioning is that GHC cannot float out the call to `newSTRef` because of how the state token is threaded through the computation in `ST`s `Monad` instance. In #11760, it was discovered that lazy ST was unsound because it allows you to create pure expressions that capture mutable variables. When one of these expression is evaluated on two capabilities simultaneously, we get nondeterministic results. According to people on that thread, strict ST should not have the same problem. I don't totally understand why. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13615#comment:43 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler