Re: concurrency (was OO in Haskell)
On Thu 07 Oct, [EMAIL PROTECTED] wrote: > See the paper "Concurrent Haskell" by Simon Peyton Jones, Andrew Gordon and > Sigbjorn Finne, which states: > > "forkIO :: IO () -> IO () forkIO a is an action which takes an action, a, as > its argument and spawns a concurrent process to perform that action. The I/O > and other side effects performed by a are interleaved in an unspecified > fashion with those that follow the forkIO." > > The paper goes on to say: > > "The situation worsens when concurrency is introduced, since now multiple > concurrent processes are simultaneously mutating a single state. The > purely-functional state-transformer semantics becomes untenable. Yes, my opinion seems to be very much in line with yours, and that of the Concurrent Haskell designers as far as I can see. Regards -- Adrian Hey
Re: concurrency (was OO in Haskell)
<[EMAIL PROTECTED]> wrote, > Manuel M. T. Chakravarty writes: > > <[EMAIL PROTECTED]> wrote, > > > > > I'm not surprised you are puzzled. Concurrent Haskell, as > > > implemented in ghc, does NOT preserve referential > > > transparency, nor could it. > > > > Of course it does! If it wouldn't many of the optimisations > > performed by GHC would be invalid and you would be doomed if > > you compiled a Concurrent Haskell module with -O (actually, > > you would most certainly already be doomed without -O). > > > > Check out the type signatures of the `MVar'-related > > operations and you will find that they are all nicely > > encapsulated in the `IO' monad. > > That does not help. Encapsulation within the IO monad > forces MVar operations to be explicitly ordered only > within the thread in which they occur; it does not effect > the relative order with respect to MVar operations in > other threads. Sure, a program using IO is not necessarily deterministic. > In summary, Concurrent Haskell only has declarative > semantics for an individual thread (called a process in > the paper) - the entire program does *not* have > declarative semantics i.e it is not referentially > transparent. The pure lambda calculus is not the only logic on which you can base a declarative semantics. A language based on a semantics expressed in linear logic won't necessarily be deterministic, but can be declarative. Given such a semantics, there is not necessarily a contradiction to referential transparency. Referential transparency means, IMHO, that you can replace variables by their values without changing the semantics of the program, ie, let x = e1 in= [x/e1]e2 e2 This is still guaranteed in Concurrent Haskell, and it is guaranteed due to the use of monads. This does not imply that the `=' sign above is the equality in a model that is restricted to deterministic computations. Manuel
Re: concurrency (was OO in Haskell)
Manuel M. T. Chakravarty writes: > <[EMAIL PROTECTED]> wrote, > > > Adrian Hey writes: > > > On Wed 06 Oct, Johan Nordlander wrote: > > > > Just to avoid any unfortunate misconceptions: O'Haskell definitely > > > > preserves the property we commonly refer to as referential transparency, > > > > and so does Concurrent Haskell, or any other sound monadic extension of > > > > the language. > > > > > > Hmm, I obviously don't understand what 'referential transparency' means. > > > I must say I'm puzzled by statements like this. If the presence of > > > mutable variables (and MVars in Concurrent Haskell) preserve referential > > > transparency, then why _don't_ we have referential transparency in C? > > > > I'm not surprised you are puzzled. Concurrent Haskell, as > > implemented in ghc, does NOT preserve referential > > transparency, nor could it. > > Of course it does! If it wouldn't many of the optimisations > performed by GHC would be invalid and you would be doomed if > you compiled a Concurrent Haskell module with -O (actually, > you would most certainly already be doomed without -O). > > Check out the type signatures of the `MVar'-related > operations and you will find that they are all nicely > encapsulated in the `IO' monad. That does not help. Encapsulation within the IO monad forces MVar operations to be explicitly ordered only within the thread in which they occur; it does not effect the relative order with respect to MVar operations in other threads. See the paper "Concurrent Haskell" by Simon Peyton Jones, Andrew Gordon and Sigbjorn Finne, which states: "forkIO :: IO () -> IO () forkIO a is an action which takes an action, a, as its argument and spawns a concurrent process to perform that action. The I/O and other side effects performed by a are interleaved in an unspecified fashion with those that follow the forkIO." The paper goes on to say: "The situation worsens when concurrency is introduced, since now multiple concurrent processes are simultaneously mutating a single state. The purely-functional state-transformer semantics becomes untenable. Instead, we adopt the standard approach to giving the semantics of a concurrent language, using an operational semantics." In summary, Concurrent Haskell only has declarative semantics for an individual thread (called a process in the paper) - the entire program does *not* have declarative semantics i.e it is not referentially transparent. For example, consider a program where one thread prints a value from an MVar, while another thread modifies it. The output of the program will vary from one run to another, even though its input (none) is unchanged. Tim
Re: concurrency (was OO in Haskell)
Tim <[EMAIL PROTECTED]> wrote: > For example, consider a program where one thread prints a value from an MVar, > while another thread modifies it. The output of the program will vary from one > run to another, even though its input (none) is unchanged. This is not a result of using concurrency. You see the same no input/different output behaviour in a program as simple as this: > import Random > main = getStdRandom (randomR (False,True)) >>= print (Or use the Time library.) And nothing of this breakes referential transparency. For example, > main = randomints >>= print > randomints :: IO (Int,Int) > randomints = do a <- getStdRandom (randomR (1,100)) > b <- getStdRandom (randomR (1,100)) > return (a,b) has the same possible results as > main = randomints >>= print > randomints :: IO (Int,Int) > randomints = let rnd = getStdRandom (randomR (1,100)) in > do a <- rnd; b <- rnd > return (a,b) Each time a program is run it is given a different world to start with. C is as referentially transparent as you are willing to agree that each function has an implicit IO in its type, which won't gain you anything. Even that is not really enough. "volatile" variables are MVars, and what are non-volatile variables changed in signal handlers? Uncaught type errors? Enough of that. All the best, Christian Sievers