Re: concurrency (was OO in Haskell)

1999-10-07 Thread Manuel M. T. Chakravarty

[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)

1999-10-07 Thread trb

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)

1999-10-07 Thread Christian Sievers

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






Re: concurrency (was OO in Haskell)

1999-10-07 Thread Adrian Hey

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