I’ve tried to explain the Erlang’s process concurrency model (or actors) to many folks, and they usually don’t see the value over other models. This is because they see concurrency just as a mechanism for improving performance (non blocking). So I was thinking on using the “multitasking” concept for my next presentations, and it goes something like this:
Before the Sinclair QDOS ('84) people didn’t thought on doing more than one job at the same time in a single machine, because the OS and the applications where not designed for multitasking, so you had to exit one application and open a new one every time. Why would you need multitasking if you have to close the app anyway?. Then multitasking OS came and new designs emerged from it.
Elixir is like having a multitasking OS built into the language (and the Erlang VM), so you can create new designs for solving new types of problems. Sure, that doesn’t makes sense if you are thinking just in HTTP request / response, (which is similar to opening and closing an application). But while you are receiving http requests, you could be receiving data from a queue and merging it with the response, or sending messages through a chat system, or doing a long processing job, connecting to many clients trough web sockets or storing data in memory. That needs multitasking, and while there are some strategies to manage multitasking in other languages (like using the OS processes or threads), having it built on the language allows you to build scalable, secure, fault tolerant and well designed systems.
Do you like this way of explaining it? If not, how do convince people the value of Elixir / BEAM? (I also tried with the Sasa Juric comparison table, but the answer it’s like, sure, but I will use Redis anyway! )
Sure, that doesn’t makes sense if you are thinking just in HTTP request / response, (which is similar to opening and closing an application)
Unless you want to handle multiple requests concurrently
Some people are already familiar with the advantage of Node.js non-blocking IO over Ruby or Python. However, node.js is still (at least used to be) running in a single OS process while Erlang utilizes all cores out of the box.
On the other hand in Ruby there are servers that utilize multithreading (for example Puma). However, a lot of ruby gems are not thread safe which basically disqualifies their usage in production. Actor-model concurrency and immutability of data minimizes those sort of issues.
Some languages also provide with actor-model concurrency, however, they are lacking the supervision trees!
It’s hard to elevator pitch Erlang. I think the best and concise showing off of the BEAM is
My take on explaining this would be through a bit organic metaphor:
In multi-threading computing happens at the same time, but all the threads come out of the main()/spawn/listen-accept function. Threads diverge like a tree, and so is memory allocation. When the exception unwinds the stack, it goes in a reverse direction and can be passed to parent. One thread can breach other thread’s resources/memory easily.
In BEAM, processes are more like separate cells - each has a small stack, small memory space (small isolated state easy to debug!). It is linked in a supervision tree , instead of an execution tree - which means that if some part of the program cells die, they can be rejuvenated. The execution chains can run in all directions via synchronous or asynchronous calls between cells-processes, and an exception in a process can but doesn’t have to be propagated to caller or parent - depending on many ways you can link and monitor processes between each other.
There are multitude of microservices written in Golang, Python, Ruby, Java, etc. and they seem to be doing just fine. As you have seen, this is not enough of an argument to convince people to leave the languages and tools they know and pursue something different. You’re trying to address a pain point which is just not there or is small enough that people don’t care. People won’t jump to another stack for 10% (or whatever the number may be) of quality of life improvements - they’ll rather work on bringing those QoL improvements to their current stack.
I think I sort of have given up on that after leading a merit-driven process to introduce Elixir in a company I worked for. More than half-way through, the whole thing was shut down by the higher management because of newly created engineering team’s policies about the allowed tech stacks. The decision kind of made sense from the company’s perspective, but I got burned out when we were told we didn’t meet the criteria that were actually not known to us upfront (or maybe those were just excuses after the fact…).
From the company’s point of view, in many (most?) of the cases, the technology is secondary to their business. The product is the king; then you need a good team that can consistently deliver. Does it matter what language it’s written in? Use the good enough tool for the job.
From the individual’s perspective, I’d suggest just looking for companies that are already doing Elixir or places where you’ll be in position to dictate the tech stack.
This is coming out pretty negative, but frankly speaking this is what you’re up against when you go out to people. I think an approach that would work is to rather encourage people to try out Elixir instead of convincing them that it’s better. Show them what can be easily done in Elixir but might be hard in other languages (LiveView maybe; but then there’s LiveWire…). Reach out to folks that are genuinely curious and looking for something new to learn. José’s Advent of Code live stream is a prime example.
I’m in exactly the the same place right now, and we were all the way through. A bunch of golangers arrived to the company and convinced the management that if you use golang, you would have an engineer team as good as Google
And now, they are facing the same stack compatibility issues that we’ve faced and solved. It’s so frustrating!
Maybe if you have a verry well krafted CI/CD/K8S/observability infrastructure, building a new microservice in Go for any task you need would be just fine. But I think that’s the case only for Google (so they developed a language that requires a good k8s cluster).
I have a small consultancy firm, and whenever I have a new project, I recommend using Elixir. But my clients always have the concern of lack of experienced developers. I think learning Elixir would be less burden than learning the legacy code for a new developer, and as It’s usually easier to read, in the end it matches the efforts. But I cannot prove the hypothesis.
My view has always been that I don’t see Erlang (or Elixir) as a language with concurrency but as a system, even OS, with a language. The system side has always been fundamental and the features of the language were designed for building systems, massively concurrent, fault tolerant, etc… systems. That is why they are what they are. We didn’t start out to make a functional language with actors (didn’t even know about actors) the language and its features evolved together with our ideas on how they could/should be used to build systems. That is why some things become almost trivial, I can write a fully functional supervisor in a page of code.
I don’t know if this helps you though. It is a difficult problem and I have always felt that understanding the core semantics and how and why you use them is the most difficult thing when learning a new language. You should see me trying to do classic OO in java or c#