Hacker News new | ask | show | jobs
by losvedir 1862 days ago
Several versions ago Jose talked about how Elixir is basically "done", which is so refreshing these days!

But since then, the developer experience has improved by leaps and bounds through all these improvements other than the core language. As a professional Elixir developer for the last 4 years, I'm loving it. A few improvements in the last few versions off the top of my head that have been really nice:

* Robust, timezone handling DateTime support in the standard library. I don't need Timex anymore!

* Finally a good approach for configuring applications ar run time (e.g. with ENV vars), that works for dev, test, prod and releases, via config/runtime.exs.

* Better compiler warnings verging on a little "light" type checking

* Mix.install in this release finally makes Elixir work well for one-off little scripts, since you can just throw a Mix.install([:jason, :mojito]) on top.

* LiveView is amazing, and I now keep open a LiveBook notebook for doodling in code, exploring an API, CSV, etc

* Not really Elixir, but I'm jazzed about Erlang/OTP 24 JIT support for better performance.

Basically, if you took a look at Elixir a few years ago and thought it wasn't ready, might be worth another peek now.

7 comments

> Mix.install

This is game changing for me (my life is boring). I totally didn't even know this was coming. It's like unexpected Christmas! For folks not in the know, it's been kind of a PITA to have packages loaded in an Elixir repl without a proper project. This should enable a lot more developer tooling to exist too; I'm stoked because I have one tool in particular that's going to be immediately be useful thanks to this change.

Does that mean you're going to be able to drop into an Iex.pry session right in the middle of an exs script without having to wrap it all in a project?

I always found I had to do that and found it quite annoying (working through adventofcode with elixir..)

Agreed that this is huge for quality of life - the ability of Ammonite (a Scala shell) to require remote dependencies in the script is amazing, compared to having to set up a whole project and build a jar.
Yep, when you consider a language "done", you can focus on bringing up the DX. I have been loving Elixir since 2016 and haven't looked back since, using it as my primary language for what it's good for, which is web based/distributed workloads.
Hey, thanks for this super useful breakdown. I loved Elixir looking at it a few years ago but never got productive enough in it to do more than a few smaller toy projects. I'm going to dig into it again.
Wait Elixir didn't have a good approach for env vars until recently?

That is like, item one on my list of things I need to be able to handle in a backend web application.

It had them. But if you did a System.get_env inside the config.exs/dev.exs/prod.exs etc it would be at compile time. Various patterns arose to do that at runtime, by using things like `{:system, "FOO", Integer}` as conventions, but it was always a bit ad hoc. If a lib saw that they would know to punt the actual reading to runtime, which is what many folks did before releases.exs, which runs at RUNTIME, so things like System.get_env work as expected.
Yeah, basically this. Quite ad-hoc.

The mechanism that Elixir used for providing different configuration values for dev, test, and prod (via dev.exs, test.exs, and prod.exs files), did not work well with environment variables, since those configuration files were evaluated at build time, which wouldn't work if you built, e.g., a single prod app and wanted to run it with different ENV vars in staging and prod.

Meanwhile, as of Elixir 1.10, there was a file called releases.exs which you could use to configure your release (basically a compiled artifact that included the BEAM VM runtime system that you could drop on your server to run, the preferred way of deploying production apps). However, those values didn't affect running the app not as a release, which is common when developing locally.

In the end, our organization kind of standardized on an approach of reading the ENV vars in the app start up, at the top of the supervision tree, which kind of worked in all scenarios.

But then in Elixir 1.11 there's finally a great (IMO) way of configuring: a new file called runtime.exs which is the best of all worlds. Like the old dev/test/prod files, it's evaluated when you run a mix project, so it's used during local development, and has access to Mix.env, so you can set variables based on environment. But it instead of being evaluated at build time, it's evaluated at run time, so you can refer to environment variables, too. And, it's used by releases!

So now there's a very slick standard way to configure your app, that works in all situations.

> Not really Elixir, but I'm jazzed about Erlang/OTP 24 JIT support for better performance.

I'm really interested to see how the JIT effects our app. I've seen some reports suggesting that a 20% bump in speed isn't unreasonable to expect.

Haven't had a chance to observe a lot of runtime stats yet but I can tell you that my compile times in big projects fell down dramatically with Erlang/OTP 24.0, at times with 35%.
Havent's measured by myself but I'd expect performance noticeable improvement for GraphQL apps that use Absinthe, since significant time is spent on parsing, validating and serializing data around resolvers.

See this thread in elixirforum https://elixirforum.com/t/absinthe-graphql-performance-issue...

excellent list, thanks for sharing this.
Timex was never needed. We have a library Calendar.DateTime that has all the functionality we need
DateTime was added in Elixir 1.8.0. Timex filled a vacuum for a long time, and still has a few nice convenience functions. In new codebases, I of course drop Timex, but it was very much needed until those APIs were added.