|
I think a lot of it is Elixir's niche, too. Unlike most of the languages talked about on HN, the BEAM makes no bones about what considerations it's made, and what sorts of problems it is and is not intended for. While there are a few just general warts to be found, they tend to either be obviously surface level things ("I don't like ~this~ bit of syntax"), or so deep you are unlikely to hit them (the issue with large binaries being stored off heap, and reference counted, and references only being collected when an individual process heap collects, leading to certain edge cases where large binaries remain uncollected even when they should be collected, leading to a memory leak that can eventually OOM you, for instance. See https://blog.heroku.com/archives/2013/11/7/logplex-down-the-... ). But aside from that, basically everything is intentionally considered and sensible from a "fault tolerance" perspective. And that makes it hard to criticize the language/platform; for a general purpose language, anything that doesn't jibe with your use case you can complain about. For a biased language like this, intending to solve a specific kind of problem, any decisions the language makes that don't conform to your problem domain are issues with you trying to use it for your problem domain, rather than issues with the language. Example: The BEAM isn't fast at pure number crunching; rather than complaining about how slow it is, anyone looking at a problem that requires a lot of number crunching will, rightfully, say "This is not the tool for the job". So for those problems where it -is- the right tool for the job, the cohesion between tool and problem is excellent, because the language doesn't try to be all things to all people. |
I've written many NIFs for Erlang that call out to high-performance C routines when "number crunching" is most important. I've also done it to side-step memory allocator churn for implementing binary protocols that support zero-copy semantics like Capnp by using the NIF as a kind of escape hatch where I can fiddle bits in a buffer directly.
In fact, somewhat lazily since it's low priority, I'm trying to create a decent Rust wrapper for the NIF interface so that I can attempt to get more compile time safety out of the dangerous stuff I do outside BEAM's safety net.
Other than being dangerous, since a segfault will bring down the whole VM, the other big issue is these calls block the scheduler (basically breaking the VM's preemptive abilities and creating the same limitations Akka on the JVM has when you block all the threads in an ActorSystem). However, now that R18 has dirty-scheduler support it's much easier to avoid this problem by quarantining that stuff on threads that don't muck with executing normal bytecode.