Hacker News new | ask | show | jobs
by asa400 766 days ago
As someone who was Elixir hire #1 at a company that eventually ended up with ~25 Elixir developers with a novel product that people actually used, I see people in this thread and elsewhere mentioning the unorthodox nature of the language or the supposedly poor performance, and I can tell you that none of that actually matters one way or another. The stuff that really hampers Elixir/Erlang adoption, in my own personal experience and from talking to friends who could have used it but went with other stuff:

1. From the outside, the benefits appear almost entirely theoretical, and in many cases, they are, and the issue with that is that in order to understand the real, non-theoretical benefits of having everything integrated into Elixir and OTP, you have to go all-in. Elixir has to own your app. Elixir is amazing, but when you start talking about its ability to do async IO, people say, "my language has a framework for async IO". When you start talking about its ability to automatically timeout and restart tasks and be fault tolerant, people say, "my language has a framework for network timeouts and I have systemd/k8s/whatever for application restarts". When you start talking about having ETS tables built in, people go, "I have Redis and it works amazingly well, why do I need it inside my app?" You can't adopt OTP piecemeal like you can with e.g., Tokio, or Redis, or Sidekiq, or whatever other thing. It doesn't really make sense to. Other languages might not be as powerful and not as well integrated, but through sheer force of effort, people make existing languages compose with general purpose tools and this is often "good enough". Of course you can write a single small service in Elixir, and this is fine and works, but this often runs into the issue of "now we have an Nth language beyond our normal languages, and we already have caching/monitoring/supervision figured out, so what is this actually adding?"

2. The library ecosystem is still very weak if you're used to e.g. Ruby, Python, Java, or Go (or even Rust, which already has way broader library coverage that is often significantly higher quality) and being able to find a mature driver/integration for a given API or native library. I don't know if this will ever catch up or reach a critical level where most people will find it acceptable. Stuff like the AWS library languished for, literally, years. Just critical stuff that's totally sorted in other ecosystems. This is purely anecdotal on my part, but it seems that way less people as a percentage of the whole community are working on libraries than applications. I have no idea why this is.

3. The performance - especially around latency and garbage collection - is great, but it's probably not "better enough" to actually matter in the domains where people tend to adopt Elixir. What I mean by this is, if you're already working on a project where the performance profile of Ruby or Python or Java is fine (web stuff, relatively simple network or CLI stuff), Elixir may be better in certain respects, but it's not so much better that it provides enough of a step change to make the other issues worth it. For our application, we had some very CPU intensive math stuff that dominated processing times, but we wrote that in Rust anyway, so the higher-level control layer could have been literally anything and it wouldn't have had any effect on performance at all. We picked Elixir because we liked it, but the product would not have failed for performance reasons if we had picked Ruby.

4. It is still, somehow, relatively difficult to find Elixir developers that understand OTP and the more operational concepts of the ecosystem (releases, deployments, observability etc.) at more than a beginner level. The community is still rather beginner oriented and there are a ton of folks who have done simple Phoenix apps and never gone further. I want to be clear that I mean this simply as an observation and not in a derogatory way at all. There is absolutely nothing wrong with having beginners in your community. Beginners are essential to ensure the community continues to grow and a language community without beginners is dying. But over time you have to build up a significant base of experts that can start and lead teams and companies independently, without having to rely on a class of consultants (of which the Elixir community seems dominated by - which is another conversation entirely that I will not get in to here). In Elixir, it seems like the proportion of experts has stayed small relative to the number of experts in e.g. Python, Ruby, Clojure, Go, or Rust. I can go out today and hire someone who understands the inner workings of Python as well as anyone working on the Django team. Anecdotally, as someone who has hired for Elixir roles, this seems difficult to do in Elixir, and I don't know why this is. I have been trying to understand why I have this perception and whether this perception is correct for literally years now, and I haven't been able to figure it out. (Strangely, Erlang on the other hand almost tilts too far in the other direction, with a ton of senior-level people and very few junior or mid-level.)

I could say more but it's probably better that I just leave it at that. I also want to say that I write all this as someone who really loves Elixir but wants to be honest about the issues that I have seen hamper adoption at the companies I've been at.

3 comments

Great write-up! I've been using Elixir for a handful of years now, primarily working on solo/consulting projects and in micro teams. I'd like to think I have a pretty good grasp on the language and OTP fundamentals, but I'll admit that some the things you mentioned in your last paragraph about lacking knowledge of operational concepts resonated with me.

Over the years I've tried to learn more about releases, deployments, distributed applications, fault tolerance in environments with multiple nodes, and hot code upgrades; but none of the projects I've worked on have reached sufficient scale or complexity for those things to really matter. My impression is that it's difficult to learn about these topics without real hands-on experience (something that seems hard to replicate in small/solo projects).

Would you mind expanding on that last point? I'd be curious to learn more about these knowledge gaps that you observed, as well as any recommendations for "leveling up" past them, whether it be projects that one could build to learn more, books to read, etc.

> My impression is that it's difficult to learn about these topics without real hands-on experience (something that seems hard to replicate in small/solo projects).

Maybe. Unfortunately, I don't think there's a cheat code there. Often the single best thing you can do is to put yourself near people who know what you want to know.

> Would you mind expanding on that last point? I'd be curious to learn more about these knowledge gaps that you observed, as well as any recommendations for "leveling up" past them, whether it be projects that one could build to learn more, books to read, etc.

Related to my response above, as an example of something I observed, we were able to teach people who had little Elixir experience about simple GenServers pretty quickly. They learned the API fine, understood the client/server metaphor, started making contributions to the product/codebase, great, product managers are happy. The gaps became apparent when we'd hear stuff like "the thing I wrote is crashing, in the logs I'm seeing things like `exit: genserver timeout`. What does this mean? Where do I even start?"

The issue here isn't really "Elixir" per se. The issue is that Elixir was sold to them as this quick, pragmatic functional programming language (and it is), but what they got along with Elixir-the-language was a production OTP application that was actually a concurrent distributed system that they didn't realize was a concurrent distributed system and now they have to figure out how to debug that, which might have been more than they were bargaining for. Now OTP starts to dominate the conversation.

You say you have a pretty good grasp on OTP so this might not apply to you specifically, but if I could recommend a single thing to Elixir developers, it would without question be to read as much of the Erlang stdlib documentation and source code as you can. They're really, really good and highly readable. Don't be grossed out by Erlang. Read up on genserver, supervisor, sys, dbg, monitors, links. Understand what is actually happening when a genserver boots. Understand what actually happens when a genserver crashes, and how this appears to the supervisor. Understand when to use a supervisor vs. a dynamic supervisor. Understand when you might want to use the process Registry.

If I can recommend more than one thing, it would be to just build toys and provide your own hands-on experience. Elixir, being so dynamic, lends itself to discovery-through-play better than almost anything. Build a 3 node cluster on your laptop and play with rpc to distribute work. Build a little worker pool and randomly crash the tasks. Build something that dispatches work with Registry. Build a little network server that listens for new tcp connections. Kill random processes and see how things react. Use dbg or sys or observer or the other tracing stuff to see live state. Build a release and figure out how to remote shell into it. The only difference is that a real app would have a real domain, which you'd have to learn regardless. Anyway, I hope this is useful.

Thank you for your insights!
That was a super interesting write-up for someone who has a passing interest in Elixir but was curious about some of the issues you mentioned, thanks!
If you're feeling any less interested, I hope you reconsider and still give it a shot. There are issues, but there are issues with every technology. I promise you'll learn something.
It does look absolutely interesting but I feel like I'm already downloading too many books and trying to follow too many different technologies but I'll come around.
I feel like Elixir has a split personality: on the one hand you have libraries for anybody to use out-of-the-box with their specialty syntax and all (Phoenix, et. al.) but on the other hand Erlang/BEAM are heavy-weight backend development tools, things that I would imagine most people do not want to or would not get into. This came up on Elixir Reddit the other day, somebody was lamenting how their job uses Elixir, but a handful of libraries without getting into the OTP weeds, and the replies were: "why do you care if it works?". But I understand where the poster came from, I do not particularly care for Phoenix or Liveview, they are tangentially related to what I would like to do with the language, which is write robust backend services with minimal technical overhead. I am sure Phoenix is nice but and I hope to use it one day but it is not the selling point to me.