* they really do need M:N threading (M green threads for the actors, N system threads where N ~= #CPUs),
* message queues have some complexities; it's not hard to get into a situation where messaging costs overwhelm actual work. Also, you need some form of back-pressure to keep a fast producer/slow consumer from killing everything.
Pony is actually a pretty sweet design for all of these. Complicated, though.
It's pretty trivial to construct actors out of some other message passing system. The interesting design choices in doing so are mostly down to the semantics in A) message passing, and B) scheduling/triggering/mapping-onto-green-threads/etc.
And for part A, all the other choices in the first three segments of the article are still effectively the choices that you've got to contend with: copying vs immutablity (bonus, COW mode, but still) vs ownership semantics.
Or to come at it from the other way: actors are far more featureful than is appropriate to directly compare to mere message passing semantics choices, because actors generally have some concept of error handling as a result of their relationship to scheduling, and that puts them on a whole different field.
This is something that is usually glossed over / afterthought when it is kind of a big deal in real life programming.
* Processes are extremely lightweight, orders of magnitude smaller than operating system processes or JVM threads.
* Exceptions should generally not be handled; instead, those lightweight processes are allowed to fail, and an external supervisor process will re-launch if appropriate.
* Assertions about the state of the data are effectively enabled on every line of code, so the processes crash early, before corrupting other parts of the system.
* Data is immutable, which plays a role in making those assertions happen.
You could probably strip one or two of those bullet points and/or add a couple of more, but I think that captures the highlights.
I'll toot my own horn. If you find that interesting, this is my favorite talk I've given about the above: https://youtu.be/E18shi1qIHU
[[someObject async] doStuff];
This will schedule the doStuff message to run on the runloop of the actor (=object + runloop) in question.Yep, although not listed in the article, JS would be such an example for me. TBH I am not entirely sure what's the difference between Web Workers and Isolates but for me it's more or less the same: Both allow safe multi-threading simply because threads do have separate heaps.
> dart:isolate - This library was an attempt to provide a single API that provides common concurrency functionality across Dart's web and native platforms. While useful in some cases, most users found the isolate API limiting compared to the Web Workers API. The infrastructure for supporting isolates also adds substantial overhead when compiling to JavaScript. In the future, you should use Web Workers to access concurrency on the web.
> Part of the isolate API has never worked (spawnFunction) in JS platforms, and the other (spawnFile) doesn't work in Dart/AOT (Flutter). Neither are able to use transferrable/shared memory objects
> On the other hand, the JS platform has evolved quite a bit since isolates were created:
Web workers
Service workers
Animation worklets
... and other APIs like SharedArrayBuffer
... we'd like to enable our web users to seemingly use these, with as little overhead as possible
From https://groups.google.com/a/dartlang.org/forum/#!topic/misc/...