3 ms·
Here are a few legitimate complaints about Elixir (and in some cases, its host VM, the BEAM): * No mutation support means that for some CPU-heavy tasks, it's n
by gamache 7y ago
Here are a few legitimate complaints about Elixir (and in some cases, its host VM, the BEAM):
* No mutation support means that for some CPU-heavy tasks, it's not as performant as languages that allow mutation. Some optimized algorithms that rely on mutation can't be expressed directly in Elixir or Erlang, and instead need to be linked in through a foreign function interface.
* It's not on the JVM so we don't get to piggyback on the thousands of dev-years of VM optimization and ecosystem around it.
* It isn't invented at, supported at, and marketed by a FAANG-type company. Money moves mountains and Ericsson doesn't spend as much on Erlang/BEAM as, say, Google spends on Go.
* Comparison across types is not a runtime exception, so you need to guard against crap like `nil > 1 == true` yourself.
* Erlang standard library, which is idiomatic to use from Elixir in the same way of using Java classes from Clojure, is a bit of a junk drawer of tools. There's good stuff, but you may have to dig for it.
* Elixir still hasn't nailed the balance between creating small, independent pieces of code ("applications" in Erlang-speak) and wrangling them so they can be used as dependencies from monorepos, multi-repos, etc. Umbrella projects were an attempt, I don't like them.
* There is an impedance mismatch between Erlang/Elixir's configuration system and 12 Factor® ENV-style configs. (Full disclosure, I wrote a library for this: https://github.com/appcues/config_smuggler https://github.com/appcues/config_smuggler)
* The built-in Elixir code formatter removes trailing commas from multiline lists. I mean, come on!
- verttii 7y agoCPU-heavy tasks may not be constrained as much on mutation as on the host VM architecture. The threading system purposefully prevents a thread from hogging all resources. And since you have to run every computation in a thread (process), there really is some overhead. As I'm sure you know, the BEAM is built for concurrency, not for parallelizing computations. Take Haskell for example, which is also immutable but doesn't require you to spin up processes to do computations. It handles CPU intensive tasks significantly better, but is a worse choice for highly concurrent low latency soft real-time apps because of the scheduler and garbage collector mechanisms. Edit: Btw thanks for bringing up that comparison across types issue. Never realized that. What's your solution to it? I'd write guards on functions that filter input based on types, then have a final fallback with no pattern matching that throws an error explicitly.
- gamache 7y agoI don't have a general purpose solution to comparison across types -- it generally takes the form of wrapping whatever might have yielded a `nil` value in a `case` expression. Not a big deal, but in cases where the rest of the computation would be garbage if a `nil` crept in, I would prefer if I could just Let It Crash.
- etxm 7y agoCould you use a nif for the heavy compute tasks?
- erokar 7y agoYes. Rust with https://github.com/rusterlium/rustler https://github.com/rusterlium/rustler is one popular option.
- dnautics 7y agoif I may do a bit of self-promotion, even though zig is not ready for prod (yet) I'm writing a nif system for zig that will make that whole process dead-easy. https://github.com/ityonemo/zigler https://github.com/ityonemo/zigler
- ihumanable 7y agoThese are fair points, but I would say that even though it's not the JVM, BEAM is an impressive piece of engineering with a significant amount of dev-years in it.
- markb139 7y ago>* It isn't invented at, supported at, and marketed by a FAANG-type company. Money moves mountains and Ericsson doesn't spend as much on Erlang/BEAM as, say, Google spends on Go. Indeed it wasn’t. In fact it was designed before any of the FAANG companies existed. And was specifically designed for systems that have downtimes measured in seconds per year.