RE: Re[2]: important news: refocusing discussion

On 26 March 2006 03:44, Ross Paterson wrote:
On Sat, Mar 25, 2006 at 05:31:04PM -0800, isaac jones wrote:
I have no idea if it would work, but one solution that Simon didn't mention in his enumeration (below) is that we could find a group of people willing to work hard to implement concurrency in Hugs, for example, under Ross's direction.
I'm no expert on Hugs internals, and certainly not qualified to direct such an effort, but I don't have great hopes for it. Apart from the fact that Hugs is written in a legacy language and uses a quite a bit of global state, it also makes heavy use of the C stack, and any implementation that does that will have trouble, I think.
Yes, I don't see an easy way to do it. You could have one OS thread per Haskell thread (let the OS manage the separate C stacks), a giant lock around the interpreter (to protect all the global state), and explicit yield() from time to time to simulate pre-emption. This isn't too bad, but you still have to implement GC somehow, and hence traverse all the live C stacks, and that sounds tricky to me.
I've been assuming that Haskell' was intended to encompass a wide range of implementations. If that's the case, the key point is that a Haskell' module that does not use concurrency, but is thread-safe, ought to work with non-concurrent implementations too.
To make that work, we'd need two interfaces: * one for applications that make use of concurrency. This would be unavailable on some implementations. * one for thread-safe use of state. This would be available on all implementations, and authors not requiring concurrency would be encouraged to use it for maximum portability.
Sure, I think this is a point on which we're all agreed. The portable interface could be Control.Concurrent.MVar, perhaps. Cheers, Simon

On Mon, Mar 27, 2006 at 09:36:28AM +0100, Simon Marlow wrote:
On 26 March 2006 03:44, Ross Paterson wrote:
[...] the key point is that a Haskell' module that does not use concurrency, but is thread-safe, ought to work with non-concurrent implementations too.
To make that work, we'd need two interfaces: * one for applications that make use of concurrency. This would be unavailable on some implementations. * one for thread-safe use of state. This would be available on all implementations, and authors not requiring concurrency would be encouraged to use it for maximum portability.
Sure, I think this is a point on which we're all agreed.
The portable interface could be Control.Concurrent.MVar, perhaps.
As Malcolm pointed out, using MVars requires some care, even if you were just aiming to be thread-safe. Packaged things like atomicModifyIORef are safe, but awkward, and need extra stuff to handle multiple variables. How about STM (minus retry/orElse) and TVars as the portable interface? They're trivial for a single-threaded implementation, and provide a comfortable interface for everyone.

On 3/27/06, Ross Paterson
How about STM (minus retry/orElse) and TVars as the portable interface? They're trivial for a single-threaded implementation, and provide a comfortable interface for everyone.
+1 on STM as the core interface. Why do you suggest omitting retry/orElse?
--
Taral

On 2006-03-28, Taral
On 3/27/06, Ross Paterson
wrote: How about STM (minus retry/orElse) and TVars as the portable interface? They're trivial for a single-threaded implementation, and provide a comfortable interface for everyone.
+1 on STM as the core interface. Why do you suggest omitting retry/orElse?
-1. STM is a cool little abstraction making it easy to write dead-lock free code. I haven't wrapped my head around writing _quick_ dead-lock free code, where as the MVar model has all sorts of abstractions built that make that, well, not _easy_, but the difficulties are understood. -- Aaron Denney -><-

On Tue, Mar 28, 2006 at 12:24:09AM +0100, Ross Paterson wrote:
How about STM (minus retry/orElse) and TVars as the portable interface? They're trivial for a single-threaded implementation, and provide a comfortable interface for everyone.
It may be relevant for this discussion: I believe I reimplemented STM, including retry and orElse, on top of old GHC's concurrency primitives. I say 'believe' because I didn't prove it's correct, and I only performed limited testing. However, it shouldn't be too surprising that it was possible - after all if STM can be implemented in C, why couldn't it be implemented in Haskell/GHC itself? The code is here in a darcs repo: http://www.uncurry.com/repos/FakeSTM/ Perhaps it could serve as a drop-in replacement for STM in haskell compilers which don't implement STM directly. Best regards Tomasz

Tomasz Zielonka
It may be relevant for this discussion: I believe I reimplemented STM, including retry and orElse, on top of old GHC's concurrency primitives.
http://www.uncurry.com/repos/FakeSTM/
Perhaps it could serve as a drop-in replacement for STM in haskell compilers which don't implement STM directly.
Nice idea. But your code already uses a whole heap of Haskell extensions which may or may not make it into Haskell'. monad transformer lib (requires MPTC) exceptions dynamically extensible exceptions deriving non-standard classes extended newtype deriving pattern guards Certainly, no compiler other than GHC currently implements all of these extensions. Regards, Malcolm

On Tue, Mar 28, 2006 at 10:49:36AM +0100, Malcolm Wallace wrote:
Tomasz Zielonka
wrote: http://www.uncurry.com/repos/FakeSTM/
Perhaps it could serve as a drop-in replacement for STM in haskell compilers which don't implement STM directly.
Nice idea. But your code already uses a whole heap of Haskell extensions which may or may not make it into Haskell'.
monad transformer lib (requires MPTC) exceptions dynamically extensible exceptions deriving non-standard classes extended newtype deriving pattern guards
You read the whole code? Wow! I myself would have trouble understanding how it does what it does now ;-) I could easily get rid of: deriving non-standard classes extended newtype deriving pattern guards I used GHC's exceptions, because I wanted my STM to handle them correctly, as in the STM paper. In a implementation without exceptions, I could probably get away with hand made exception handling. The rest would be a bit more difficult to remove, but I think it could be possible more or less elegantly. Best regards Tomasz

Simon Marlow:
On 26 March 2006 03:44, Ross Paterson wrote:
On Sat, Mar 25, 2006 at 05:31:04PM -0800, isaac jones wrote:
I have no idea if it would work, but one solution that Simon didn't mention in his enumeration (below) is that we could find a group of people willing to work hard to implement concurrency in Hugs, for example, under Ross's direction.
I'm no expert on Hugs internals, and certainly not qualified to direct such an effort, but I don't have great hopes for it. Apart from the fact that Hugs is written in a legacy language and uses a quite a bit of global state, it also makes heavy use of the C stack, and any implementation that does that will have trouble, I think.
Yes, I don't see an easy way to do it. You could have one OS thread per Haskell thread (let the OS manage the separate C stacks), a giant lock around the interpreter (to protect all the global state), and explicit yield() from time to time to simulate pre-emption. This isn't too bad, but you still have to implement GC somehow, and hence traverse all the live C stacks, and that sounds tricky to me.
True, but so what? I mean, honestly, we should decide language features by their merit to applications and maturity. We should also take into account what the power/weight ratio of a feature is in terms of general implementation costs. But discussing the costs to one particular implementation that's already been stretched light years beyond what it originally was intended for, seems a bit much. Manuel
participants (7)
-
Aaron Denney
-
Malcolm Wallace
-
Manuel M T Chakravarty
-
Ross Paterson
-
Simon Marlow
-
Taral
-
Tomasz Zielonka