Unravelling Elixir
It all happened while I was reflecting on the state of programming languages. If you’ve read some of my other posts, you’d know how much I dislike Javascript for the bloated powerhouse it is. Rich food is great but when it gets too rich, it becomes sickening. Apparently, programming languages follow the same pattern.
Javascript, that ever popular language that fashionably claims to make life easier for the developer, has curiously produced some truly convoluted ways to do simple things. In its current state, JS looks like the molecular gastronomy of programming. Fancy, sometimes even incredibly so, yet rarely does it beg for a repeat experience.
So here I was, daydreaming about getting back to my former love C++11, when I stumbled upon this article on Medium. Do yourself a favour and read it! Trust me, it’s life-changing. I read it of course and after that, I gave some time for the message to settle in then… Boom!!
So let’s explore my mind blowing excitement. Lots of great points made in this article. These words specifically got my attention:
Why does it take so much knowledge and experience to become somewhat productive in OOP? It really comes down to design patterns… design patterns are nothing more than a band aid for the shortcomings of OOP.
- Suzdalnitski, Ilya, “Why is OOP Such a Waste?” (Medium, 2021)
Design Patterns
Have you ever read the illuminating Design Patterns: Elements of Reusable Object-Oriented Software by E. Gamma, J. Vlissides, R. Johnson, R. Helm? If you have read this great grimoire on solutions to tackle classic OOP problems, you’ll realise that Suzdalnitski’s article brings to our attention that design patterns are nothing more than a clever way to solve problems we could avoid altogether.
Let’s take the Singleton pattern. It’s essentially a way to ensure unicity in a world created with plurality in mind: a clever construct built within the rules of the system to provide a rather complex solution to a simple problem.
In the cult of OOP, design patterns are the 10 commandments. If you follow them religiously: they begin to make sense.
Mutability
In most dynamic sites and applications, Data needs to change to reflect the results of user interaction. In programming, mutable and immutable refer to the state of an object and how variables can be assigned and changed.
Mutable objects can be modified (or mutated) after they are created, and transformed into other data or variables.
In Elixir, objects are immutable. Immutable objects are unchangeable after creation. They’re like a statement of fact or a source of truth. The data or variable will stay the same. To work with new data, you’d need to make a copy of the object and use the copy from that point onwards.
Your first reaction might be to notice that the constant need to copy objects will generate an overhead in terms of processing time and memory. You would of course be right, but…
Please think about threads: the clever concept allows running the same code concurrently in a very efficient way… until you need to access a shared resource. To do so, a thread has to shout out its intent to all the other threads, forbidding them to use the shared resource until it’s done with it. The lock put in place is known as a mutex and the whole scenario is called a bottleneck.
So if you can get over the overhead that comes with mutability you’ll gain scalability.
Scalability
Looking at the usual ways one scales up most web apps, you can:
- Upgrade your server to get more oomph.
- It’s easy enough to implement. The downside? Price. More power means investing in a better CPU, having more cores and RAM. Also, if your one server dies on you, so does your application.
- Start a new server and put a load balancer in front of your group of servers. This suffers from the same issue of price but reduces the worry when one server suddenly dies. Of course monitoring and restarting new servers requires extra software layers. Also, if the load balancer goes, so does the application.
- Use Docker and Kubernetes to orchestrate your needs.
- Is this the miracle solution? Docker is a keeper, the ideal tool to democratise development in a team and deploy without hassle, right? Now, add Kubernetes for easy scaling up and monitoring of the containers.
- This comes with a learning curve and a lot of extra software layers: your onion just swelled to the size of a watermelon! You won’t be deploying an application anymore, you will in fact deploy a whole ecosystem. There’s also a cost to mapping Docker containers to hardware. At this point, your app shouldn’t die though, but the cost of its immortality might just be too much for your wallet.
By now, you should be wondering about the Elixir approach to scalability, so here it is:
- Erlang’s OTP, the engine that runs Elixir’s compiled code, is horizontally scalable on CPU cores and servers in the same subnet! The VM will spread the load and you’ll enjoy an immortal app at the price of the servers deployed to host it.
Don’t believe me? Then chew on these nuggets:
- Try googling “Elixir + Discord”, or “Erlang + WhatsApp” ?
- How many application frameworks achieve a “nine nines” reliability (99.9999999%) ?