
Bruce Eckel
...shared-memory concurrency is impossible for programmers to get right...
Explicit locking is impractical to get right. Transactional interfaces take much of the pain out of that -- even web monkeys can get shared memory right with SQL! When two instances of a web app interact with the database, they are sharing the database's memory. So you have locking, mutual corruption and all that jazz -- yet you seem to be message passing! More generally, applications backed by network services -- which are presented through a message passing interface -- are shared memory applications much of the time (though a bright service can tell when modifications are unrelated and run them in parallel). Message passing certainly makes it easier to write parallel applications, but does it provide any help to manage shared state? No. None whatsoever. If you have a bunch of programs that never share state with one another, they are a single application in name only. Using locking as your default mode of IPC is harrowing, but you can do anything with it. Using message passing is simpler in most cases, but you'll have to implement locking yourself once in awhile. Language level, transactional interfaces to memory are going to cover all your bases, but are rare indeed -- as far as I'm aware, only Haskell's STM offers one.
...the unnatural domain-cutting that happens in shared-memory concurrency always trips you up, especially when the scale increases.
This is true even with transactional interfaces. Message passing is _like the network_ and makes you think about the network -- so when it's time to get two servers and hook them together, you are already ready for it already. Transactional shared memory is not at all like the network. Why not? In a transactional system, a transaction can not both be approved and unwritten. On the network, though, these are separate messages, going in different directions -- they can fail independently. -- _jsn