8 ms·
I won’t let a friend start development in Elixir. Let me get it out: I love BEAM. OTP is awesome and one of the best systems in its kind. I was completely enam
by xlii 2y ago
I won’t let a friend start development in Elixir.
Let me get it out: I love BEAM. OTP is awesome and one of the best systems in its kind. I was completely enamored with Elixir years ago as a modern Erlang which excited me to the bone.
It’s no longer the case. When you get into non-trivial things there are many sharp edges and paper cuts. Some from the top of my head:
- it’s impossible to disable warnings - test runs are often highly verbose because libraries ignore them and (as discussed somewhere in forums) warnings are deemed useful so they can’t be disable
- the only way to catch some, important ones, in CI is to use "warnings-as-errors" …
- so one cannot use deprecation flags because it’s also a warning
- when having non trivial ecosystem one cannot selectively deprecate and get errors, this has to be a human process (remember to replace…)
- when doing umbrella tests on non compiled code seed influences order of compilation
- this order of compilation influences outcome and can lead to buggy code
- dependency compilation is not parallelized - takes a lot of time and uses 10% of CPU
- compilation process can break and Elixir isn’t aware that it was interrupted - this means that it doesn’t try to compile properly app/dependency but instead tries to release crippled one
- documentation is hard to use - searching shows random versions and there isn’t even a link to „open newest”
- searching in docs often not finds the keywords you can actually see
- a lot of knowledge is implicit (try checking if you can dynamically add children to a Supervisor)
- sidebar with new ExDocs break for some reason so there is no navigation
- there is no way to browse navigation outside this broken ExDocs which outputs only HTML and LSP
- LSP is afterthought, there are few but neither works well
- Dialyzer/dialyxyr typespecs are useless most of the time
- Squiggly arrow works weird (i.e. ~0.3 might catch 0.99) - my colleague recently mentioned Renovate not picking it up
I could go on and on. I’m doing plenty of research so I’m working with various languages including „niche” ones like Prolog, OCaml, Clojure, Cuelang. Recently I’ve been developing tooling in Go and many core systems are developed in Rust in Elixir, and I work on the latter often.
In principle Elixir is awesome, but has the worst developer experience of all. Sometimes it takes 4h to prepare and push release. Tooling I’m working on can do the same in 5 minutes - I’m parallelizing processes in containers, making idempotent output artifacts and heuristic failure detection to retry on flakiness. When switching between Go and OCaml you can sense how tooling cares for me and my time. Often I bounce off forums where people’s need are shrugged off as non-essential, treating those who came as uneducated juniors (because who in sane mind would like to have a parallel dependencies compilation or disable compilation time warning).
There is nothing better than BEAM, but (for me) Elixir got much worse over the years.
- simoncion 2y ago> - a lot of knowledge is implicit (try checking if you can dynamically add children to a Supervisor) What? This is very clear: <https://www.erlang.org/doc/apps/stdlib/supervisor.html#start_child/2 https://www.erlang.org/doc/apps/stdlib/supervisor.html#start...>, as is this: <https://hexdocs.pm/elixir/1.18.3/Supervisor.html#start_child/2 https://hexdocs.pm/elixir/1.18.3/Supervisor.html#start_child...>. What am I missing? > - this order of compilation influences outcome and can lead to buggy code Do you have an example of this? It's my understanding that the big thing about both Erlang and Elixir are that they're functional languages, it doesn't matter what's compiled when. Is this some nightmare compile-time code manipulation thing? > ...searching [the docs] shows random versions and there isn’t even a link to „open newest” Is scrolling to the top of the list contained in the version selector near the top left of hexdocs.pm not good enough? If not, why not?
- dqv 2y agoThey are probably talking about the child spec needing a unique ID if it's the same module being started. The docs problem is more of a Google problem. For some reason Google still only shows the 1.12 docs for a lot of searches. The sidebar issue was fixed more recently, I think in the last year. But basically the sidebar wouldn't get loaded until Mermaid finished loading, so it was updated to defer loading of Mermaid. The latest version of ExDoc shouldn't have this problem.
- simoncion 2y ago> They are probably talking about the child spec needing a unique ID if it's the same module being started. No, my experience says that's not true. I have this code in one of my projects and it works just fine: -behavior(gen_server). start(Mod, Args) -> supervisor:start_child(secret_project_worker_sup:getName(), [{Mod, Args}]). I can spawn as many of those guys as I like and they all become children of the named supervisor. The named supervisor is a 'simple_one_for_one' supervisor with a 'temporary' restart policy. I guess the thing that might trip folks up with how the docs are worded is not noticing this further up in the document A supervisor can have one of the following restart strategies specified with the strategy key in the above map: ... * simple_one_for_one - A simplified one_for_one supervisor, where all child processes are dynamically added instances of the same process type, that is, running the same code. and that 'start_child/2' accepts EITHER a 'child_spec()' OR a list of terms -spec start_child(SupRef, ChildSpec) -> startchild_ret() when SupRef :: sup_ref(), ChildSpec :: child_spec(); (SupRef, ExtraArgs) -> startchild_ret() when SupRef :: sup_ref(), ExtraArgs :: [term()]. and that only the 'child_spec()' type can have an identifier, so the first bullet point in the list of three in the function documentation does not apply. Also, I find the way the docs USED to print out function types a bit easier to understand than the new style: <https://web.archive.org/web/20170509120825/http://erlang.org/doc/man/supervisor.html#start_child-2 https://web.archive.org/web/20170509120825/http://erlang.org...>. (You will need to either close the Archive.org nav banner or scroll up a line to see the first line of the function type information, which is pretty informative.)