"More than one thing at a time"

On a recent Elixir Outlaws episode Chris Keathley told us all a nice story of the advantages of Elixir as opposed to Ruby. His frustration with Ruby and appreciation of how Elixir works resonate at the frequency of my own frustrations and joys. I believe my titular quote is accurate, that's one of the primary things he noted. How nice it is to use a runtime that can do more than one thing at a time.

And I've never really used Ruby. What I have used is a lot of Python. And some Node.js. And I find the way they execute, async or not, to be frustrating and firmly in the camp of mostly sufficient. Not aspiring to greatness.

I really like Python. I enjoy using it. I'm skilled enough with it. I can see why people like Node.js to some extent. I understand that Node.js allows you to stick to a single language and provides a bunch of other interesting possibilities. Some of them are unique to JS. But I find both lacking when I compare their technical underpinnings with the BEAM which Erlang and Elixir runs on.

Efficienct resource usage is an effective cost reduction

Chris mentioned how many instances running the ruby service they could drop and replace with much fewer Elixir instances. This is bound to end up saving Bleacher Report a bunch of money over time. That wasn't the point of it all but I think people should keep in mind that performance directly relates to cost. Especially in the cloud.

With auto-scaling cloud infrastructure the effects of strong utilization of resources can be very noticeable on the bill. Being competently concurrent and parallell means better utilization of the CPU's you are paying for. Providing better latency guarantees by means of the BEAM scheduler's pre-emptive scheduling as compared to single-threaded cooperative multi-tasking means that you reduce the risk of a single dodgy code-path or an odd piece of data processing blocking the event loop for a significant time.

The capabilities of your runtime sets limits on your potential

You can build great things in basically any language on any platform. And a lot of languages have distinct strengths that are not strictly technical but would take enormous effort to dislodge from the ecosystem where they were born. Such as Python and machine learning which is a matter of library support rather than technical fitness and it dives deep into C/C++ to extend Python in a performant way. Node.js has huge developer mindshare, a vast library ecosystem, near-native cross-platform app development that cannot be replicated without Javascript because of app ecosystem restrictions and it enjoys exclusive ties to frontend development.

Python won't unlock a stronger concurrency and parallellism story unless it manages to get rid of the GIL. So building highly performant web services in Python will always include paying attention to these limitations and working around them. That doesn't make it impossible or even particularly hard but I've worked with systems where the GIL was definitely a factor. Much as the single-threaded nature of Node would have been.

The BEAM VM, Erlang and OTP were built for creating reliable distributed systems. It does that well and has a strong core feature-set for that. The distributed computing story incidentally transfers well to online services such as web applications. The approach it uses with inexpensive processes and message passing also translates very well to multi-core workloads.

This is an incredible foundation to stand on. Elixir gave it a more approachable and dare I say modern language that people had an easier time getting going with. Erlang was already a great success for some companies but somewhat under the radar.

I firmly believe that this gives any appropriate application or system built on this foundation a much higher ceiling before the runtime and core building blocks actually start limiting progress.

When I see ideas about porting something born in the Elixir ecosystem, such as Phoenix Presence or LiveView to Node.js I usually scratch my head. I get why they'd want it but I don't believe in the idea. Both of those are examples of strengths of the BEAM, reliable stateful services in distributed applications. Data is maintained across the cluster, there is a strong approach for limiting damage (supervision trees, etc) if a process holding data breaks due to a bug, an outage or similar. You can clone the surface of LiveView or Presence and go "BAM! Node has it too". But I bet it doesn't.

Pay attention to the trade-offs (if you want to make something great)

This doesn't just hold true for Elixir. There are also plenty of places where Elixir and the BEAM would be the wrong choice. Consider React Native (or NativeScript, Capacitor, Cordova, Ionic, any cross-platform tool for making apps) for example. Most people are aware that they are making a trade-off when selecting React Native. And most people are probably right about picking it anyway. Because making native apps is expensive and time-consuming and you just want iOS+Android and they should be basically identical anyway.

By choosing the cross-platform tool you are probably binding yourself to a decent app. But you are limiting your potential to make it great. Technically you could drop into native implementations per platform with React Native. Just like a Python dev can always "just write some C". That's not normally why you'd choose the tool. You might even recruit based on the tool and not actually have anyone that know C, Swift or Kotlin that could dive deeper.

The best mobile apps are typically done natively in the intended tools. They fit in, they can integrate with all the relevant APIs of the operating system at the full level of detail without abstracting away the differences. They can take advantage of any optimizations the platform owner makes and they do not get screwed over by incompatibilities quite as often.

We see the same thing with Electron apps (and equivalents) on the desktop. There the problem is more directly felt because the overhead of running them is ridiculous compared to what the apps actually do. They all run a full browser. The amount of resources used by Slack, Discord and Spotify is maddening. I try not to think about how fast they could be, how lean. In Spotify's case, how fast, lean and useful it actually once was. And how much more efficiently they could do things.

So for mobile apps and desktop applications the potential for greatness is higher when working with the languages and tools that are well suite to the task. The same is true for web development. Stateful and distributed or even stateless thanks to the soft real-time latencies, I think Elixir and the BEAM have an incredible high ceiling for technical achievements compared to most comfortable high-level languages that it compares to. So consider what your language and ecosystem provides you and if it is in line with what you value. If that checks out, you are doing fine. If it doesn't maybe something to think about.

I grant that I'm biased towards Elixir, BEAM and OTP. But I do really like Python. I just have frustrations with it. I don't hate Node either, I'm just not sure I like it. If you want to follow my writing this blog has a completely normal RSS feed and you can sign up for my newsletter further down. If I'm very wrong or you have thoughts, questions or concerns feel free to get in touch via lars@underjord.io or just find me on Twitter as @lawik. It is not my intent to pee on your ecosystem, I just have feelings and opinions. I'm sure it's a fine ecosystem.

Latest Posts

Asking a tech recruiter

While working I mostly found the attention of recruiters slightly reassuring but often annoying. I think that annoyance is fairly common, usually built up from countless LinkedIn drive-by attempts from unreading keyword-hunting recruiters. I thought that now, out on my own, maybe this legion of recruiters can be my sales department....

Read More

The Mac is losing me

I've been mostly happy using a Mac since I got myself my first computer earned with programmer money. I believe it was a mid 2009 15" MacBook Pro. That was a computer I used at least until 2016 which I consider very decent usable life. At that point I had replaced the hard-drive with an SSD, upgraded the RAM and switched a battery that was worn out. I stopped using it when it just straight died some time in 2016....

Read More

The BEAM marches forward

The BEAM is the virtual machine that Erlang and Elixir runs on. It is widely cited as a battle-tested piece of software though I don't know in which wars it has seen action. It has definitely paid its dues in the telecom space as well as globally scaled projects such as Whatsapp and Discord. It is well suited to tackle soft-realtime distributed systems with heavy concurrency. It has been a good platform chugging along. And with a small team at Ericsson responsible for much of its continuing development it has been managed in a deeply pragmatic way. Erlang has always been a bit of a secret and silent success. Almost no-one uses it if you look at market shares. But among the ones that use it there seems to be a very positive consensus. And then Elixir came and caused a bit of a boom. I think the BEAM has benefited from Elixir and Elixir wouldn't exist without the BEAM. With that bit of background I'd like to shine a light on some cool developments that I think makes the BEAM more interesting or even uniquely interesting in the future....

Read More
Read All Posts →