4 ms·
What does Erlang offer that the JVM or .NET don't?
by apta 6y ago
What does Erlang offer that the JVM or .NET don't?
- yawaramin 6y agoCheck out the OP.
- dnautics 6y agoThe concept of failure domains is baked into the runtime, and not an afterthought.
- smabie 6y agoWhile there is actor support through Akka and Akka.net on the JVM and .NET, neither of them support preemption like the BEAM does. Preemption of blocking actors is a game-changer in terms of how you write and structure concurrent code. I wrote a BitTorrent client in Scala using Akka and found myself desperately wishing that I could write actors in a blocking style. The amount of extra complexity and book-keeping required to write purely non-blocking actors is truly staggering. Let me give you an example. I have an actor that asks for two objects from a DbActor, and then sends them to the AdderActor to get the sum. Without preemption, I have to do the following. 1. Send a message to get object A and object B. Return. 2. Wait for an object. 3. When I get the object, figure out if it is object A or B (or maybe it's something else entirely). Update internal state so that I know I need one more object. Return. 4. Wait for an object 5. Get the object, figure out if it is object A or B (or something else). Update internal state so I know that I have both objects. Send the two objects and my Add message to the AdderActor. Return. 6. Wait for the result. 7. Now that I've gotten the result, update internal state saying that I've completed my A+B operation. Either store the result of A+B or whatever. This method requires a lot of internal booking and a lot of mutable hash tables in order to keep track of all the various stuff this actor is in the process of doing. If I'm trying to calculate A+B and C+D, I need to know how far along I am in each computation. This is a buggy and annoying process that creates a ton of complexity. Let's look at how we could do it in Erlang: 1. Send a message saying we want object A. 2. Don't return, and instead block until we get A. Now we ask for B. 3. Block until we get B. Now send the A+B message. 4. Block until we get it. Do something. Return. See how much easier this is? Because we can block, our code actually can be structured to look like normal, non-concurrent code. It can be executed in a sequential fashion, even though the actual computation is happening somewhere else. With Akka and Akka.net, we can't do that. We have to return as quickly as possible, or else we are going to lock up the entire system. This means that all of the implicit state that a normal program has (like current line being executed), must be stored explicitly by our program. It sucks, but hopefully the JVM will get preemption sometime soon. The actor model doesn't really work with out it. And even though it doesn't work without it, it's still better than threads and mutexes.
- apta 6y agoAs you point out, the JVM is getting preemption by means of Loom. .NET already has coroutines (async/await) so it should already do what you stated.
- smabie 6y agoI'm not super familiar with .NET, but if it supports preemption, they why this? https://getakka.net/articles/concepts/actor-systems.html#blocking-needs-careful-management https://getakka.net/articles/concepts/actor-systems.html#blo... Coroutines in general are a form of cooperative multi-tasking (they must explicitly yield), but I might missing something about .NET's implementation.
- apta 6y agoIt is specific to blocking APIs, as per the page: > Examples are legacy RDBMS drivers or messaging APIs, and the underlying reason is typically that (network) I/O occurs under the covers The issue with async/await is that APIs need to be extended with their async counterparts. If they don't, then you have to be sure not to invoke blocking calls. Java won't have this issue as the runtime will take care of preemption.
- sbalea 6y agoIn Scala/Akka, you could use the ask operator and compose the resulting Futures, something like this: for { a <- aProviderActor ? gimmeA b <- bProviderActor ? gimmeB aPlusB <- adderActor ? (add, a, b) } yield aPlusB
- smabie 6y agoYeah, but you're blocking the thread. It's very very easy for you to deadlock the entire system writing code like this.