it looks really awesome! Can someone point out the negative sides (or drawbacks of any kind) ? What about finding elixir experts/freelancers? What about integration with .Net and the xamarin forms ecosystem?
1. no static typing. With typescript having taken off, and now even python and ruby becoming more and more feasible to use in production with static typing, switching to a new dynamic language is a hard sell for me.
2. limited ability to take full advantage of some of its unique features in many cases. The runtime and the included OTP library/paradigm has some really cool features with its approach to processes and concurrency with the actor model, and features like hot code reload. But IMO the industry and popular best practices have evolved in a different direction that make these things less compelling. Code deploys are a solved problem in any of the major vm/container runtimes, with blue/green deploys, canary builds, feature flags, etc. all quite easy to use, so hot code reloading isn't that compelling as a language feature anymore. There are tons of ways to orchestrate multiple instances of a services from Heroku to Kubernetes, and APIs built on Protobuf and GRPC, GraphQL, or json REST APIs, are now pretty standard for communicating between different services, or using message queues, kafka, cloud pub/sub, etc. Also the paradigm most developers are familiar with is stateless app servers that store any state in database or cache layers, which has a lot of benefits.
Erlang and OTP seem to kind of mix all of these paradigms together, and if you use all of its built-in ways of doing things you are really striking out on your own from the common "best practices" that more developers these days will be familiar with. A lot of common tooling and cloud hosting providers don't support Erlang OTP style programming natively. It can certainly be used successfully, I believe Whatsapp as one famous example was originally all written in Erlang, but I personally don't see a whole lot of justification for most apps to do this. Of course you don't have to use any of these features, but then why use a language if you're not going to lean into its unique strengths?
> limited ability to take full advantage of some of its unique features in many cases
Honestly, this shouldn't count as a downside. :) The way I frame it is "in the worst case scenario, you can deploy Erlang/Elixir as you would any other language".
You don't need to use distribution, you can still build stateless apps, etc. And yes, almost nobody uses hot code swapping!
However, whenever you need a specialized solution, such as quick messaging between servers, proper concurrency so a slow upstream server doesn't kill your app, etc... you have that at your fingertips!
Even if you are not using any of that in production, you are still leveraging concurrency when compiling code, running tests, etc. It really makes a large difference! And if for some reason you cannot leverage any of that either, the languages are still great on their own. Pattern matching and immutability are a joy, developers feel productive within the existing frameworks, and so on.
My car can go 260km/h but I never went past 140km/h (speed limit where I live) and I still love it (the best car I ever had).
static typing is what drew me to go, Elixir isn't a static-typed language, but there are plenty of guardrails in the language that make up for it. Pattern-matching, guards, good compiler messages, casting, etc.
You've also got fantastic testing framework, and good conventions like tagged tuples {:ok, x} vs {:error, y}.
On top of all of that, you've got the Erlang underpinnings: immutability, crash-fast, app umbrellas, etc.
It's a very safe language to develop in. I don't miss the strict static typing at all.
> limited ability to take full advantage of some of its unique features in many cases. The runtime and the included OTP library/paradigm has some really cool features with its approach to processes and concurrency with the actor model, and features like hot code reload. But IMO the industry and popular best practices have evolved in a different direction that make these things less compelling.
Think about it this way. You already reap a lot of benefits by just handling requests with Phoenix. Pre-emptively scheduled light-weight processes that does not have to run GC in most cases is already a huge win. Don't you think?
You certainly don't have to be 100% buy-in in every single OTP or Beam feature. Really. Actually, it makes sense to do things "the old" way when you feel more confident about them.
> 1. no static typing. With typescript having taken off, and now even python and ruby becoming more and more feasible to use in production with static typing, switching to a new dynamic language is a hard sell for me.
While it's true that Elixir is a dynamic language, there's much less "magic" compared to Ruby or PHP, the language server has good autocompletion and warnings.
Yeah, I can't really tell if the overall community will adopt it or not, but you may well be right. Last time I commented something about ruby not having static typing I got downvoted by people claiming Sorbet is already used heavily in production.
But either way if I'm switching off of ruby, I don't really want to go to something else that doesn't have static typing.
A few huge companies like Stripe use Sorbet. Thats really not a good representation of Ruby users though. I guess youre right, for dynamicism Ruby is awesome but if you need types just switch to a true typed language.
I've been involved in interviewing for Elixir positions and found that we got more senior candidates than I've ever seen before. Part of it might have been pandemic displacement. But I'm not seeing a lack of work in my freelancing and I'm not seeing any particular skill shortage.
.Net and Xamarin integration. No clue. Samr as for any other non-.Net language I imagine.
I've never seen anyone complain about this, so maybe I'm alone, but the runtime error messages are absolute garbage. Especially if you get an unexpected nil that bubbles up, you'll often see cryptic erlang messages that don't really identify what went wrong. (Think type errors that don't identify the expected type nor the type passed.)
And by that same line of thought, it's frustrating as a functional language given its almost complete absence of built-in monadic types and helpful sugar to use them. Instead of `Maybe`/`Option`, for example, you pass tuples around tagged with atoms. This wouldn't be the end of the world except that...
There's no static typing. Which means that `match` blocks can't enforce completeness. This isn't a huge deal, but for a dynamically typed language, it's surprisingly cumbersome to introspect at runtime. Languages like Ruby make such things first class, such brings me to...
Elixir is nothing like Ruby. With the exception of `def`, `unless`, and `do`, there are nary a few similarities. This isn't necessarily a negative, but the whole notion that Elixir and Ruby share syntax is only barely—and completely superficially—true. In large part, this is because...
There is no method-style syntax. That's not uncommon for a functional language, but it's problematic when the standard library is hugely inconsistent. Is the function you want in the `List` module? Or the `Enum` module? Or is it part of the `kernel`? Hunting around for the right module is a pain, but not as bad as...
Inconsistent naming of functions. Sometimes they're fully spelled out; other times they're abbreviated. And if you're really unlucky, if it's in the kernel, you can expect 1970's Unix-style abbreviations that are so short to be unreadable and have no consistency in how they're formed. US state abbreviations follow more strict rules than Elixir kernel function names. At least one thing Ruby got very right were easily-guessable method names.
There's a lot of good in Elixir; don't get me wrong. But I've spent over a year in it and keep stumbling on very un-aesthetic issues. For such an otherwise wonderful developer experience, these pain points ring loudly.
Frankly, unless you need a lot of parallel things to happen behind the scenes in real-time, I just don't see much use case for Elixir. Its ability to fail and keep going (a major selling point) is great, except that I find it too easy to write code that fails, which can bubble up and create inconsistency in its state. I much prefer something that will help me avoid failure in the first place (Rust us great for that), or something that lets me code fast and loose and makes that experience really enjoyable (like Ruby).
I think I'm alone in these criticisms, however, because I never really see anyone talk about them, so take this all with a grain of salt. I have used a ton of languages in my 25 year career, and I had a lot of hope for Elixir. But, frankly, I just don't get it.
For highly parallel networked applications, it makes sense. For very small things that would otherwise need external service dependencies (Redis, sqlite, etc), it makes sense.
But if your focus is any other use case, I really struggle to justify its adoption. It's not as fast as advertised for anything non-realtime parallel. (Go, Java, Rust, et al all provide much faster alternatives.) It's not as quick to whip up for medium sized projects. (Like Rails.) And it's not as fault tolerant as something like Rust, which can help you avoid the faults in the first place.
LiveView—the latest "must have" for web development—is likewise disappointing, in case that intrigues you. Single-language back- and front-end development sounds great. But it's just back-end streamed to the front end, which is problematic for any significant latency. None of the benefits of front-end except not refreshing the page. It's a fun (and very impressive) toy, but you get almost none of the benefits of a real front-end app. (Such as UI changes while the data is loading.)
While I only have a little experience with LiveView, I have plenty experience with latency-laden server-side echoing to know that when it breaks down without the client doing its own best-guess updates, nobody will have a good time.
Maybe I'm just salty because I expected the Elixir experience to be more than it turned out to be. And I do enjoy some of the things it forces you to do, by virtue of its being a functional language. But at the end of the day, I personally find its warts to be significant and not worth dealing with outside of very specific use cases that it uniquely handles very well.
Your mileage may vary, but I would ask yourself: does my application needlots of real-time, parallel functionality? If the answer is anything short of "hell freaking yes!", then I would look elsewhere for serious development.
I appreciate all the hard work Jose and Chris (and of course all others) have put into their respective portions of the Elixir experience. But I think it was oversold. And I think the number of packages that haven't been touched (or issues responded to) in over 3 years may indicate that others struggle to find its value in many areas in which it was advertised to be a game changer.