I am in the design phase of a programming language, currently thinking about the concurrency aspects. I need to figure out a consistency model, i.e. how data is handled by concurrent processes programmed in this language.
There are two important criteria:
My two candidates right now are non-blocking software transactional memory on one side, and copying message-passing semantics without sharing a la Erlang.
I'm particularly worried about ease-of-use, so I'll present the major arguments I have against each of these two models.
In the case of STM, the user must understand what members of a class must mutate atomically and correctly delimit atomic code sections. These must be written so that they can be repeated an undefined number of times, they may not perform any I/O, may not call some foreign functions, etc. I see this as far from easy for a non-experienced programmer.
Erlang-style share-nothing concurrency is attractive, but there is a catch: real-time processes cannot copy the objects they send over, because they cannot perform any memory allocation, and so objects have to "move" from one process to the other via queues. The user must be aware that if one real-time process has two references to an object, both those references will be cleared if he sends the object to another process. This is a little like weak pointers that may or may not be null at any point of use: it may be surprising.
I tend towards the second model because it appears easier to understand and it naturally extends to distributed systems.
What do you recommend?
I have done a little with Erlang, not much, but although the share-nothing message passing paradigm was new for me I would say that it was easy to understand in visual and physical terms.
If your language is to be widespread, I would say that the Erlang-style is at least something I can wrap my mind around without too much work. I assume others will be able to learn and apply that kind of model easier than the STM method.
I'm not speaking from experience, but it seems like the Erlang model would be easier to implement, as it doesn't have to deal with a lot of the low level memory operations, you just share nothing, and manage the memory passing between processes.