Which boils down to problems created by the POSIX implementation with condvars, mutex and semaphores. No lockless and waitfree data structures.
With threads there are also minor hidden contants: limited stack size, high cost of context switches.
And random order of evaluation.
Lockless threading semantics needs to know ownership, copy or ref and relationship to be able to fix these problems. I only know a few not well-known languages who actually did a solve these problems.
My hunch: that modern programming often requires concurrent execution of software, but that most ways in which we have to model concurrency in code are at best hard to learn, and are frequently orders of magnitude harder to learn and use.
Node.js is pretty good in this sense. Except for the very hard parts, because of node's async nature, you can introduce good amount of concurrency in your code by default, resulting in a decent amount of IO being concurrent. You have to get used to a fully-async programming model though.
It would be the mainstream languages problem then or something. Concurrency with actor model is easier to learn and use than OOP, which many people seem to be able to use.
I find a lot (most?) OOP code I read is either spaghetti (with weird object interdependencies), diffuse (waay to many classes and subclasses so following the flow of computation becomes difficult) or both. It's a great tool, but perhaps harder than widely realized.
And concurrency is even harder, especially with the ever-popular "tweak until it parses/compiles, then ship" approach, or when many people are working on the same section of code.
The Hewitt Actor approach reduces independencies dramatically, at some cost for certain algorithms, and with added clarity for many others. And it scales somewhat automatically beyond one machine which is a big win these days.
The actor model is non-deterministic and doesn't solve all concurrency problems, such as creating fine-grained or irregular data parallelism. There isn't (and it may not be possible to have) one single solution to 'the concurrency problem'.
Actor model is very deterministic, but it can model unbounded non-determinism, i.e. any concurrency problem. Including fine-grained and irregular data parallelism. It's up to the compiler to generate SIMD instructions out of it, if that's what you mean.
How co you argue it’s deterministic? If one actor asks two other actors to do a job and send the result back, those results come in a nondeterimistic order. That’s a race condition. It’s easy to write programs with bugs in them because of this.
Something like fork-join is deterministic because results come in a fixed order.
And for generating SIMD from actors? Or handling irregularity efficiently? I feel like you’re making the ‘sufficiently clever compiler’ argument.
We cannot currently efficiently solve all parallelism problems in practice using actors, and we don’t know how we would be able to.
Non-deterministic order is not a race condition. You also need some sort of shared resource and being unaware of said non-deterministic order of incoming messages. With actor model you can't have shared resources and can't be unaware that messages come in no specific order.
And I'm not arguing for a sufficiently clever compiler, just that you can express any concurrency with actors. You can definitely create a convention backed by actors that compiles into SIMD if you need it.
Which boils down to problems created by the POSIX implementation with condvars, mutex and semaphores. No lockless and waitfree data structures.
With threads there are also minor hidden contants: limited stack size, high cost of context switches. And random order of evaluation.
Lockless threading semantics needs to know ownership, copy or ref and relationship to be able to fix these problems. I only know a few not well-known languages who actually did a solve these problems.