Hacker News new | ask | show | jobs
by collaborative 1023 days ago
I'm a seasoned Java and Node developer, but have never touched Elixir/Erlang. Could you spell out for me the benefits Elixir provides over Java concurrent code? Is it actually a performance gain, or simply a nicer syntax? I am a bit confused by the claims of this post and of the earlier comment. Thanks a lot
2 comments

So, when you're working with Elixir or any language on the BEAM VM, you're in a world where data is immutable and processes are isolated. It's like having Akka's actor model but at the VM level, so it's super integrated.

The BEAM VM itself is a different beast compared to the JVM. It's more like its own mini-OS designed for real-time multitasking. Each process has its own garbage collection, and it's all non-blocking. So if one process goes belly-up, it doesn't take the whole system with it. Imagine a network of telephone switches; if one gets zapped by lightning, the rest keep chugging along. That's the level of fault tolerance Erlang and BEAM were designed for.

Now, speaking of fault tolerance, let's talk about how easy it is to mess up an Akka system if you're not careful. Say a new Java dev joins your team and doesn't get Akka's actor model. They might introduce shared mutable state between actors, which is a big no-no and can lead to all sorts of race conditions. Or they might do something like put a blocking operation inside an actor, which can hog resources and mess up the whole system's performance. Akka's great, but if you don't follow its principles, you can still shoot yourself in the foot.

So, the beauty of Elixir and BEAM is that a lot of these good practices are enforced by the VM itself. You get that fault tolerance and concurrency baked right in, without having to rely on every engineer knowing all the best practices.

Hope that clears things up!

That's interesting, thank you! Now I have new things to learn on my list :)
I recently saw a talk on Youtube about "structured concurrency" in Java. It looked pretty interesting. But it seemed to me the way to achieve parallelism is by starting on a procedural code flow and as you come to a part that can be parallelised, you split into a bunch of tasks in a scope and that scope will monitor how those are executed. Once the results are accumulated, we go back into the procedural flow. This is similar to what is done in go IMO and is a pretty good technique.

In Elixir, on the other hand, you could create a module which is like a server process. You can start this server in a procedural flow, or you can "connect" it to a supervisor by giving it the startup information needed and a strategy to be used on how to restart the process in case it crashes for some reason.

A client process (or processes) with it's own module can then send messages to the server which will handle the incoming messages in its inbox sequentially. If you squint at it from an angle, modules look like classes in that they provide a way to separate code logically.

This way of doing concurrency takes getting used to and has a higher initial learning investment. But it feels cleaner and is less prone to user errors. In go for example you have to be careful of closures and shadowing which will result in shared memory and hard to debug errors, even though the initial investment in learning Go is much lesser.