In this blog-post we want to share a recent experience we had with the Elixir dev community.

The premise

Many of our products are based on Elixir, a dynamical function language that runs on the BEAM Erlang machine. Since we have a lot of shared business logic in our products we have grouped them all together in a common Elixir app.  This common app has a development cycle of its own, so releases happen more often than product releases. For now, all good.

The symptom

This common app defines many Elixir structs used across all products, like notifications, protocol configurations, domain objects, etc. An Elixir struct is like a map with a name with some more constraints. Being a weak-dynamic typed language, Elixir provides compile-time checks for structs, i.e. checking that one only uses existing fields in the struct.

Clients of the common app have it as a local dependency (actually is a git sub-module) that one needs to update by-hand once a new release is out. We started noticing a strange behavior when compiling code that uses the common app. The problem was that after updating the common app, the compiled code would violate the struct contract by having extra fields (that previously existed) that were removed from the struct. We also found out that only SAVING the file (forcing its recompilation) would solve the problem.

The cause

After doing a little experiment we found out “mix” (the build tool for Elixir) was not recompiling code that uses those struct when they change, thus bypassing the compile-time guarantee. We smashed our heads against the wall a little, thinking that was our problem (as it usually is) to later conclude that this was a bug on the mix tool (which we did not expect).

The technical cause was (as we later found) that mix didn’t take into account changes in structs for marking the clients of that code as dirty and recompile it.

The solution

After being able to reproduce it consistently we put together a minimal example showing the failure and filed an issue to the Elixir core dev community on Github [1] on Wednesday. The next day one of the core-developers took the issue and after a little discussion the issue was solved [2] on the same day (merged to master 🙂 ). This shows the frenetic rhythm of the Elixir community.

It was a great experience to see the bug fixed (since that prevents many headaches for us) and also to contribute (a little) to the Elixir community. We are now eagerly waiting the next release to update our stack and get this fix in our code.