Hey Jose, thanks for your comment. I actually wanted you to notice, because Elixir is still one of the best languages out there (and BEAM is the best), but developer experience IMO is deteriorating over the years.
It's not a problem for people who are completely immersed and can remember most of the guidelines/policies/idiosyncracies. Getting new people on board or even following guildeilnes is hard when work process is interrupted. Some paper cuts are brought on Elixir Forums but I've seen them evaluated as not providing enough benefit to developers or being against design - and I found them through trying to solve very similar problem. I like some changes in devex direction (e.g. recent LSP initiative), yet I think it's lagging to other languages.
I often get cut by various - often small things - but there are so many. Disappointed is amplified by good experience with other (I'll give it to them - more popular or better funded) languages. Yet given very static download count of Jason on Hex I think that rarely new projects are started in Elixir, while Erlang's popularity is slowly but visibly growing, so I don't think I'm alone in my perception.
I will try to respond succintly to followup to not blow up already large text, so let me know if you'd like more info. https://imgur.com/a/iWbTEUf I've uploaded some weirdness I experienced in recent weeks/months.
> (ExDocs breaking) ... please give an example
In screenshot - happened with Chromium,Safari and Firefox ~6 months ago. Often with OTEL libraries. Today I can't reproduce, but I also have DNS blackholing enabled. Maybe it's fixed or maybe that was analytics breaking on me.
> WRT: checking if you can dynamically add children to a Supervisor
Our case was bug caused by change of Dynamic to Normal (we had an app that would be replace in specific context, but otherwise should be supervised as usual). After that we started observing comm channel blocks due to dead connections - it was 77 1/2 bug: Line 77 shut down the child and Line 78 deleted the child, in 77 1/2 Supervisor restarted the child so it couldn't be deleted anymore - and it was able to pick some comm channels. It's not hard to fix, but one has to know that. I don't like "not recommended", as many things aren't recommended but we do it given circumstances. It's better to know the difference and being able to make decision by oneself.
> Also note docs are available in the terminal, both inside `iex` or by doing `mix help SomeModule`
`mix help Ecto` shows missing task, so I suppose it's a typo (or something I don't have). Help in `iex` (and probably `iex -S mix`) requires dependency download, build, maybe rebuild and some flag and env manipulation (so that app doesn't start entirely) and I hope I started it before breaking compilation because otherwise it won't. Yes, it's there - I agree, but it takes energy to use.
> ...but note we have always listed the versions in the sidebar
I know, however as text moves places the worst possible example of it is like: Search for A - open - notice wrong version - check which one I should be using in code - change to version B in sidebar - not linked, got bounced to home page - search in ExDocs - nothing found (searchbox often fails to return results, see screenshot) - get back to search engine - type exactly version and query - click there. When it repeats multiple time it starts to become unavoidable busywork.
I'm 99% sure that it's a result of circular dependencies and maybe one pass fails but then the other starts overwriting or something. But could also be something in compilation pipeline (we have extra steps). I wish there was something like "mix elixir_checks.compile_consistency" (with a flag to send a bug report). Right now feeling a bug means: isolating and justifying it. It takes energy, especially when codebase is complex, big and ridden with prior decisions. I considered doing that, but I think environment is defensive and I'm easy person to pull into fights, but don't enjoy them.
> "dependency compilation is not parallelized"
I made a mental shortcut - i.e it's using only one core right now, and it's taking approx. 2-3 minutes. Looks like PR would resolve it, but not sure when we'll be able to use it.
> when doing umbrella tests on non compiled code seed influences order of compilation
In short (I don't know cause) if I run `mix test` from umbrella I'm seeing different compilation order on applications and their dependencies (if I hadn't compiled those before). Those applications aren't guaranteed to be in homogenous dependency state (in fact when I'm looking for dependencies in `mix.exs` I can see popular libraries spread across 3-4 different major versions). Unlucky run happens and consensus is "don't debug `rm -fr _build`).
> Our philosophy here is to emit compilation warnings instead of compilation errors whenever possible, so you can run, debug, and test your code, instead of forcing your code to be pristine while you are still working on it.
This is big pain point for me. I care about some warnings, but not for others (e.g. in libraries that ale planned to be dropped ). I also can't enable those I'd like (deprecated - so my colleagues don't use something we want to sunset in root or dreaded circular dependencies). I solved this by complex check chain and custom filters, but in "competition" I get those out of the box.
I won't say that Elixir is worse technology it's just... I know others which are better (but not BEAM, BEAM is THE BEST)
> Yet given very static download count of Jason on Hex I think that rarely new projects are started in Elixir
So you are getting the download count of one package, one that has been added to Erlang/OTP (and Elixir itself) and is more than expected to decrease in download count, to estimate the popularity of the whole language and a ecosystem of 20k+ packages? And over what time period exactly?
> (ExDocs breaking) ... please give an example In screenshot - happened with Chromium,Safari and Firefox ~6 months ago. Often with OTEL libraries.
Got it. I was reminded that there was unfortunately one version of ExDoc with a sidebar bug and they probably were still using it. If you ask the package authors to update `ex_doc` and republish the docs, it should take 2 minutes to fix it. They might already have done it though.
Regarding ExDoc's search, people have been asked for improvements, such as searching on latest version by default and searching across packages. I am glad to say there is work happening towards this area (including soon the ability to search across all of the dependencies of your own project).
The other bug in your screenshot, about Ecto.Query, please report it if you can reproduce it. It is indeed a "wat" bug but I am not sure what could be causing it. EDIT: I was told this may happen if you are using a mocking library, here is a reproduction and a bug report: https://github.com/jjh42/mock/issues/151 - if you are using mocking libraries, please double check if they can be the root cause.
> I made a mental shortcut - i.e it's using only one core right now, and it's taking approx. 2-3 minutes. Looks like PR would resolve it, but not sure when we'll be able to use it.
It should not be using one core, even it if compiles one dependency at a time. My whole point is that you get parallelism from within the dependency/project.
> when doing umbrella tests on non compiled code seed influences order of compilation
Honestly, I have no idea how this could possibly be the case. Elixir's seed is applied per process and, in this case, it is only applied to the process running your tests, which is not the process related to compilation at all. I will drop a comment in your other thread about cycles in your umbrellas, which is also not possible.
> I can see popular libraries spread across 3-4 different major versions)
This is also something that should not be possible. I mean, you can specify different major versions, but the dependency resolution will guarantee they all agree on a single one. For example, you can't have different versions of `Jason` in the same umbrella, unless there is something really unconventional or undesired on how you are building your umbrella apps. So I would need a mechanism to reproduce it in order to pinpoint what. I would double and triple check your apps configuration, it seems there is something really unexpected going on.
> I would double and triple check your apps configuration, it seems there is something really unexpected going on.
More than one thing for sure. It's big and highly heterogenous ecosystem (multiple umbrellas) in distributed environment with high idempotency requirement. Without safeguards decisions were made that today make things very complicated. It's difficult to challenge long used patterns without hard recommendation or concrete evidence (I looked into Perceived Complexity analysis for Elixir but couldn't find anything).
My organization now builds the story of "Elixir codebase is hard to work and unreliable - let's switch to other tools". I don't like that story because I still remember all the fun I had and all the systems I produced that stood years with 0 maintenance. But those were small teams and small projects and today it's an enormous Jenga tower that's risky to breath around.
I would go as far as to say that our codebase is somewhat of a Petri dish for all kinds of issues (especially on dev/test envs, but not only). I've seen code merged to main branch because it wasn't picked up as changed and used stale cache, multiple-Elixir and OTP versions used in compilation, arch spillovers and more.
>I can see popular libraries spread across 3-4 different major versions), This is also something that should not be possible.
We have overrides and I don't see the umbrella test helper so I guess that umbrella-level overrides don't play nice with non-compiled in-app test runs.
> I am glad to say there is work happening towards this area (including soon the ability to search across all of the dependencies of your own project).
Looking forward to it, one thing that I often change too, is changelog across libraries, so it would be nice to always have those up-to-date.
> It should not be using one core, even it if compiles one dependency at a time. My whole point is that you get parallelism from within the dependency/project.
Project or a single-dependency compilation is fine - I felt different after recent updates to our stack and won't complain. In one umbrella I have opened I see ~250 deps packages and deps.tree shows me ~6500 lines of output, some of those are compiled multiple times - I blame the loops.
I have similar CPU - 8 performance cores and 4 efficiency ones. Usually deps.compile takes less than 100% of total CPU with spike to 150%. On partitioned tests I can feel the warmth of 1100% CPU usage (it also makes me smile, because I like big numbers). Right now I'm thinking that maybe I could spawn ~250 containers, make each compile dependency and then merge output into one and see what broke ;-)
> So you are getting the download count of one package, one that has been added to Erlang/OTP (and Elixir itself) and is more than expected to decrease in download count, to estimate the popularity of the whole language and a ecosystem of 20k+ packages?
Not ideal, but the best I could find. I also looked at Ecto which is standard, but figured out that json is more often used in projects than a database. Given quality of software itself I'd expect steady increase on the "core" libraries. But I also hear from prior projects about them being sunsetted. 2 or 3 projects in Elixir less, no big deal. In current organization few of us are actively advocating for Elixir and BEAM. We're minority and newcomers encounter as a first thing difficult stack setup (Erlang and Elixir version) long compilation time, hundreds of odd warnings and LSP that takes 40s to pick up on changes and highlight some errors.
--
I'm not in position of making any demands, it's self inflicted 99% of the time, and it's not a bug that can be fixed upstream it's just a subjective experience, and I wish it could be better.
I am sorry to hear. I understand it may be something out of your control but it seems you have clearly identified some "smells" that would be worth spending some time investigating.
For example, you can't have loops in deps, and therefore ~250 deps should not print a 6500 thousand entries long tree. At least, for this particular problem, you can isolate your project structure, without any code, and try to reproduce it externally. And, while you can override deps, the goal of an umbrella is to share dependencies, so overriding an umbrella sibling dependency is a smell too.
You said it's an enormous Jenga tower that's risky to breath around but it seems at the same time no one wants to invest on an air purifier. If it is of any help, you can look at the Remote case on the Elixir website (https://elixir-lang.org/blog/2025/01/21/remote-elixir-case/), they have a large codebase, around 15k files, 300 engineers (several dozens being Elixir ones), and while their codebase is healthy, you can see they had to invest on some "bottlenecks" that appeared along the way, such as CI times. And the need to invest in the code base itself will be true of any language as time passes. Best of luck!
Thank you. I completely agree and I'm not going to back out (nor switch technology at this). I hope that one day I will be able to open-source some of the work and help others who struggle. In the meantime I'm looking forward to deps compilation time speedup and documentation tooling (not to mention 1.19). My own experiment of parallel isolated builds showed speedup comparable to the one you mentioned, but I dislike hacks so I'd rather wait for peer reviewed version :)
We didn't and probably won't but we're exploring area of write Elixir code without Elixir code, i.e. heavy code generation. Some of us keep fingers crossed for the upcoming type checks, some of us are working on dev tooling (we have a looooong wish list of stuff to have, like dataflow traces, maybe some lightweight proofing, distributed version tracking etc.) but it's all about devex as app itself is rock solid and stable.
I have my own personal project that very quickly started to suffer from similar project and I move between tech, and given very good experiences with Go, that's something I'd be looking at. I like async and Go has fun async and great tooling to break/fix code.
There are some things that rubbed me wrong way about it. Like typing but still giving way to runtime errors in specific scenarios or lack of macros (which is what makes Rust great to work with because otherwise it’s just sea of boilerplate eventually).
IMO the more sensible decision would be moving „down”. One still has to use some Erlang in Elixir (for example for tracing) and there are small benefits I appreciate lately - like visual differentiation between variable and an atom.
Runtime errors? As far as I know Gleam will never present runtime errors unless you manually add `todo`, `panic` or `let assert` statements. [1]
I feel you on the macros, I have wanted them too, but I respect the language creator's commitment to minimalism, and I don't feel that e.g. JSON decoders are too much effort. It seems the language is headed down the route of code generators rather than macros, which seems like a reasonable tradeoff to me. [2]
Yes, that’s let assert on pattern matches. We’ve briefly evaluated Gleam (but I only very shortly) and result was that we cannot port existing code any way and integration would be very difficult (especially given missing macros).
I do, however agree with you on macros and code generations. My hand in Rust is macro heavy (I dislike boilerplate) but in Go I learned to appreciate codegen utilities and it might be the way to go.
The topic itself is interesting, because I’ve been doing „business logic in types” and it’s impossible to pull of without invoking so much magic that keyboard starts to emit indigo and that puts Gleam in akward place because when we are at that place maybe it’s easier to write code generation with Prolog/Cue but instead of putting another layer just settle with Erlang/BEAM assembly.
But my problems are more in domain of „what happens when during daylight saving shift I receive an out of order message that should be included in generated raport of order fashion and one of node died at that point”.
It's not a problem for people who are completely immersed and can remember most of the guidelines/policies/idiosyncracies. Getting new people on board or even following guildeilnes is hard when work process is interrupted. Some paper cuts are brought on Elixir Forums but I've seen them evaluated as not providing enough benefit to developers or being against design - and I found them through trying to solve very similar problem. I like some changes in devex direction (e.g. recent LSP initiative), yet I think it's lagging to other languages.
I often get cut by various - often small things - but there are so many. Disappointed is amplified by good experience with other (I'll give it to them - more popular or better funded) languages. Yet given very static download count of Jason on Hex I think that rarely new projects are started in Elixir, while Erlang's popularity is slowly but visibly growing, so I don't think I'm alone in my perception.
I will try to respond succintly to followup to not blow up already large text, so let me know if you'd like more info. https://imgur.com/a/iWbTEUf I've uploaded some weirdness I experienced in recent weeks/months.
> (ExDocs breaking) ... please give an example In screenshot - happened with Chromium,Safari and Firefox ~6 months ago. Often with OTEL libraries. Today I can't reproduce, but I also have DNS blackholing enabled. Maybe it's fixed or maybe that was analytics breaking on me.
> WRT: checking if you can dynamically add children to a Supervisor
Our case was bug caused by change of Dynamic to Normal (we had an app that would be replace in specific context, but otherwise should be supervised as usual). After that we started observing comm channel blocks due to dead connections - it was 77 1/2 bug: Line 77 shut down the child and Line 78 deleted the child, in 77 1/2 Supervisor restarted the child so it couldn't be deleted anymore - and it was able to pick some comm channels. It's not hard to fix, but one has to know that. I don't like "not recommended", as many things aren't recommended but we do it given circumstances. It's better to know the difference and being able to make decision by oneself.
> Also note docs are available in the terminal, both inside `iex` or by doing `mix help SomeModule` `mix help Ecto` shows missing task, so I suppose it's a typo (or something I don't have). Help in `iex` (and probably `iex -S mix`) requires dependency download, build, maybe rebuild and some flag and env manipulation (so that app doesn't start entirely) and I hope I started it before breaking compilation because otherwise it won't. Yes, it's there - I agree, but it takes energy to use.
> ...but note we have always listed the versions in the sidebar
I know, however as text moves places the worst possible example of it is like: Search for A - open - notice wrong version - check which one I should be using in code - change to version B in sidebar - not linked, got bounced to home page - search in ExDocs - nothing found (searchbox often fails to return results, see screenshot) - get back to search engine - type exactly version and query - click there. When it repeats multiple time it starts to become unavoidable busywork.
> - "compilation process can break and Elixir isn't aware that it was interrupted" - our tooling has code to deal precisely with this: [https://github.com/elixir-lang/elixir/blob/c5c87a661efac6809...](https://github.com/elixir-lang/elixir/blob/c5c87a661efac6809...). If it still happens, it is a bug and must be reported, so we can fix it
I'm 99% sure that it's a result of circular dependencies and maybe one pass fails but then the other starts overwriting or something. But could also be something in compilation pipeline (we have extra steps). I wish there was something like "mix elixir_checks.compile_consistency" (with a flag to send a bug report). Right now feeling a bug means: isolating and justifying it. It takes energy, especially when codebase is complex, big and ridden with prior decisions. I considered doing that, but I think environment is defensive and I'm easy person to pull into fights, but don't enjoy them.
> "dependency compilation is not parallelized" I made a mental shortcut - i.e it's using only one core right now, and it's taking approx. 2-3 minutes. Looks like PR would resolve it, but not sure when we'll be able to use it.
> when doing umbrella tests on non compiled code seed influences order of compilation In short (I don't know cause) if I run `mix test` from umbrella I'm seeing different compilation order on applications and their dependencies (if I hadn't compiled those before). Those applications aren't guaranteed to be in homogenous dependency state (in fact when I'm looking for dependencies in `mix.exs` I can see popular libraries spread across 3-4 different major versions). Unlucky run happens and consensus is "don't debug `rm -fr _build`).
> Our philosophy here is to emit compilation warnings instead of compilation errors whenever possible, so you can run, debug, and test your code, instead of forcing your code to be pristine while you are still working on it.
This is big pain point for me. I care about some warnings, but not for others (e.g. in libraries that ale planned to be dropped ). I also can't enable those I'd like (deprecated - so my colleagues don't use something we want to sunset in root or dreaded circular dependencies). I solved this by complex check chain and custom filters, but in "competition" I get those out of the box.
I won't say that Elixir is worse technology it's just... I know others which are better (but not BEAM, BEAM is THE BEST)