There is this intriguing snippet in the docs for elm/core Process:
Right now, this library is pretty sparse. For example, there is no public API for processes to communicate with each other. This is a really important ability, but it is also something that is extraordinarily easy to get wrong!
I think the trend will be towards an Erlang style of concurrency, where every process has an “event queue” that anyone can send messages to. I currently think the API will be extended to be more like this:
type Id exit msg spawn : Task exit a -> Task x (Id exit Never) kill : Id exit msg -> Task x () send : Id exit msg -> msg -> Task x ()
One thing missing, how does a spawned task receive messages ? Well it could do it by either polling or blocking:
poll : Task x (Maybe msg) -- Nothing if none available
recieve : Task x msg -- Blocks till there is one
And that completes the API into a minimal, non-TEA like, concurrency model that could be backed by a real threaded Elm runtime. Not in the browser obviously, since Javascript there is single threaded, I am interested in exploring this topic hypothetically, as a thought experiment.
What is the right concurrency model for multi-threaded Elm ?
We could have mutable Dicts, like Haskells MVar, software transactional memory (STM), something else ?
Actor model does seem like the most natural fit to Elm, as TEA itself is very actor like.
I have written before that Actor model is bad for Elm, but to be clear, that is when talking about purely single threaded Elm. My view is that it makes single threaded programs harder than is strictly necessary to understand and modify, and that a better structure is achieved through functional abstraction and shared flat models sliced up using extensible records, as opposed to defunctionalising, out messages, and actor model.
But that is not to say that I believe Actor model is a bad concurrency model, and when real parallelism is available, it is arguably the safest. There is no shared mutable state, eliminating an entire class of race conditions, and multi-threaded programming can be very hard, so we appreciate concepts like this that can make it simpler and safer to do.
A downside of Actor model is that it is coarse grained parallelism. You don’t have things like parallel for loops, or the flexibility of coroutines to turn sequential looking code into parallel without necessarily reorganizing it around an Actor model.
Actor model is well suited to more static parallel pipelines. In my view that is actually a good thing - in a really high performance system you want to think of CPU cores themselves as Actors, and deliberately create a system that maps onto the hardware, as opposed to creating thousands of threads, on per job, and losing the benefits of going parallel to task switching overheads.
I have create a more TEA-like Actor model API, and the built a simulation of it running in Elm, to get a feel for what working with it would be like.
I will follow up with that next, but now my wife wants to watch our series on TV, so later… but if anyone has some ideas on how best to introduce multi-threading into Elm or even concurrent distributed Elm oper many machines, I would be interested to hear them.