12 ms·
All languages end up with simple concurrency primitives such as async/await. No one takes the next steps and introduces the high-level primitives you actually
by dmitriid 6y ago
All languages end up with simple concurrency primitives such as async/await.
No one takes the next steps and introduces the high-level primitives you actually need to work with actors and concurrency in a sane manner: monitors, messages, supervisor trees. Erlang has been around for thirty years, people.
- Someone 6y agoFTA: ”This is a common pattern: a class with a private queue and some properties that should only be accessed on the queue. We replace this manual queue management with an actor class […] Things to note about this example: - Declaring a class to be an actor is similar to giving a class a private queue and synchronizing all access to its private state through that queue. - Because this synchronization is now understood by the compiler, you cannot forget to use the queue to protect state: the compiler will ensure that you are running on the queue in the class's methods, and it will prevent you from accessing the state outside those methods. - Because the compiler is responsible for doing this, it can be smarter about optimizing away synchronization, like when a method starts by calling an async function on a different actor.” The article also links to - https://forums.swift.org/t/concurrency-actors-actor-isolation/41613 https://forums.swift.org/t/concurrency-actors-actor-isolatio... (pitch for implementing actors) - https://github.com/DougGregor/swift-evolution/blob/actors/proposals/nnnn-actors.md https://github.com/DougGregor/swift-evolution/blob/actors/pr..., which links to https://github.com/DougGregor/swift-evolution/blob/actors/proposals/nnnn-actors.md https://github.com/DougGregor/swift-evolution/blob/actors/pr... (proposal for implementing actors) I don’t know Erlang well, but what’s missing?
- dnautics 6y agoMonitors, linking, supervision trees, vm-level introspection into the state of the actors, distribution primitives that make actor identity nonlocal across clusters, actor cancellation (like kill -KILL), graceful actor shutdown, sane id serialization (how easy is it for me to serialize an actor Id, put it on a kafka queue and have it come back in a response so I can route the response back to the actor) etc, etc, etc.
- dnautics 6y agoadditionally if you go to Elixir, they've implemented async/await on top of the not-really-"actors" of the erlang VM in its standard library, and it's super easy to use and understand. Arguably easier than async/yield/await like exists in most languages that use async as a coroutine serialization primitive.
- Thaxll 6y agoBecause it's not a language feature it's an entire runtime / paradigm.
- dmitriid 6y agoNo idea why you're getting downvoted, but you're right. ONe of the reasons why Erlang allows for monitors, and supervision trees and many other niceties are precisely because the VM is built that way: Processes are isolated. Even if one process suddenly dies, the VM will take care of cleanup and will notify any monitoring processes, etc.
- ardit33 6y agoasync/await are not primitives. Mutexes, semaphores, atomic counts etc... those are true primitives in multithreading and they have been around forever (since the 70s at least). I feel the Swift lang. design is like amateur hour at its best, trying to reinvent the wheel, but still end up where it started, but at worse overrall usability. Just re-arranging chairs. 8 years later, and still Objective-c + GCD combo is better at multithreading. In comparison: Java had decent multithreading support since version 1.1,(one year later after its release) and it had NIO by JDK 1.4 and full modern multithreading by JDK 1.5. Swift is a couple of years behind because it is trying too hard to be cool and different.
- rubiquity 6y ago> async/await are not primitives. Mutexes, semaphores, atomic counts etc... those are true primitives in multithreading async/await, a way to model concurrency, and mutexes/semaphore/etc, a way to safely share data, belong to separate categories and one does not preclude the usage of the other, especially if your coroutines are allowed to run on different threads.
- asimpletune 6y agoI don’t think they meant one precludes the other, and “modeling concurrency” definitely is a “sharing data” problem. In other words, you would have to build a nicer concurrency abstraction out of a lower level primitive at some point.
- machello13 6y ago> worse overrall usability You can definitely find iOS/macOS developers who prefer objective-c, but they're in the minority. The vast majority would say that Swift is way, way more usable than Objective-C. Obj-C still has some advantages (dynamism being a big one) but for most tasks Swift makes developing both easier and more safe.
- kitsunesoba 6y agoComing from several years of writing Obj-C, Swift has certainly been a net benefit for me. Writing it well does require a bit of a shift in one's way of thinking (writing "Obj-C in Swift" is a recipe for pain) but I find that once that hurdle is cleared it's a very productive language to work with.
- pjmlp 6y agoReally? https://www.ponylang.io/ https://www.ponylang.io/ https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library https://docs.microsoft.com/en-us/dotnet/standard/parallel-pr... https://dotnet.github.io/orleans/ https://dotnet.github.io/orleans/ https://microsoft.github.io/coyote/ https://microsoft.github.io/coyote/
- dmitriid 6y agoReally. Only one of them is barely beyond experimental (Pony). The rest are experimental projects.
- pjmlp 6y agoToday I learned that Halo is an experimental game.
- spinningslate 6y agoOK, OP was somewhat remiss in saying "no-one". But you have, I think, missed his point. Instead, substitute "few mainstream language designers" and it stands up. By mainstream I mean Java, Javascript/Typescript, C#, C, C++, Python and such. Most have introduced async/await. None has meaningfully gone beyond that as far as I'm aware. Working with Erlang's concurrency model is a refreshingly simple, consistent mental model compared to the mismash of concurrency features provided by the mainstream. In Erlang, it's as simple as: 1. Do these things need to happen concurrently? No: regular functions. Yes: spawn regular functions. Compare that to the mainstream: 1. Do these things need to run concurrently? No: regular functions. Yes: are there only a few, and/or do I need strong isolation? Yes: use OS-level processes No: do I want the OS to take care of scheduling / preemption? Yes: use threads No: use async/await Is there a chance that my async operations will be scheduled across multiple OS threads? No: get speed boost from no scheduling overhead, but remember to yield if there's any long-running actions. Yes: build my own likely-buggy, half-baked scheduler Oh, and as a bonus: run back up the entire call stack to make all functions that call mine async. And that's before we get to error handling. I'd take Erlang supervision trees _every day_ over trying to figure out which nested async callback function generated an exception.