Growing Elixir Applications

Elixir is an awesome new language with some amazing capabilities. It brings with it the power of an amazing framework in OTP, which has been built and used over the better part of two decades.

On top of this, new frameworks have already been built and are maturing nicely. Pheonix, the web framework, is already an amazing front runner that makes it easy to build an incredibly performant website.

Ecto adopts the Repo pattern for database access and already has great support for a growing number of databases. Postgres has first class support for some of its newest and favorite features. It provides easy wrappers for relations of many types as well as support for using Postgres extensions like jsonb.

All these things make it easy to start a new project in Elixir and get it up and running quickly and simply. Spinning up a new blog, a new chat app with live updates over websockets, or an online store becomes as easy as it is in languages that have been around for years.

A quick aside for the less familiar. Elixir not only comes with easy & free interoperability for any Erlang based library, it has a robust dependency management system called Hex. Hex is like RubyGems and Bundler all rolled up if you’re coming from the Ruby world. It allows you to specify dependencies in a file and does version resolution to make things work. It sticks with a more strict `locking` strategy, where gem versions are hard locked into a lock file. But I’ve digressed.

Elixir already provides most of what developers of much older languages are used to. I struggle not to call them more “mature”, because in my view Elixir is mature because of its toolchain.

As a developer, that toolchain makes all the difference. For starters:

  • repeatable builds based on locked dependencies
  • stable, pluggable, easily accessible REPL for trying things out
  • generators for new projects with:
  • projects like Phoenix can provide their own templates for generators of their own
  • prebuilt deployment workflows (some battle proven for years inside Erlang)

All these things that just waste developer time ordinarily are handled. Every hour I spend time debugging an app that worked just fine last time I worked on it is an hour I’ve wasted. Having a prebuilt toolchain allows me to skip that shit and get with building new features.

So, basically, Elixir is magic and it just makes everything perfect and easy and perfect and it’s a magical world right?

Not quite.

Elixir and the Erlang zero-cost pass-trhough means that we have to play by the majority of Erlangs rules.

Erlang is a functional language, and variables are immutable unless explicitly freed.

So we’re functional, not object oriented. Which means that variables aren’t objects and so we can’t have state that mutates.

Which, as we’ll see, is actually pretty fucking awesome.

What all this means is that it will force you explicitly manage state that you need. See, when I came to Elixir from Ruby what I realized is that I was using a fuckload of hidden state. I was using objects to store state without actually thinking about why I needed that state, or how to access it.

By making all of that handling explicit, and it impossible for someone to alter state in a way that you don’t want, a developer has to design her state.

After working this way for a while, I found that when writing Ruby most of my bugs (and usually the most tricky ones to solve) were found in mismanaging my objects state. Something was changing state where I didn’t expect, or some state was getting duplicated instead of altered in a way that it wasn’t falling through.

Quite simply, that can’t happen in Elixir. Variables are immutable, which by definition means that no one is reaching in and fucking with your shit. State is handled explicitly, so when I update it, I know. I have to do it purposefully. Not only that, I have to write code that allows me to manipulate that state.

All this makes for fewer bugs, fewer hours spent debugging, more time building features.

Oh, and how can I forget. As a compiled language, a majority of my stupid typo mistakes get caught at compile time. Now, I know that a lot of people, myself included struggle hard getting used to a compiler. They spend time “fighting” it and think it’s time wasted.

Here’s the thing though, that code wouldn’t have ran in a non-compiled language. It would have failed at runtime, hopefully getting caught in tests, at which time it would have blown up anyway.

I like to not only think of the compiler as my friend but as a baseline level of tests that I get for free. You still need to write the appropriate tests and make sure that going forward you’re doing all the things you need to do, but I don’t need to waste a bunch of boiler tests making sure that my interfaces are adhered to. I get those for free when I get my code to compile.

I feel the need to include several paragraphs of what I’m not saying in regards to test but I’m going to give y’all the benefit of the doubt that you know that I’m still saying you should write tests when they make sense.

Many, that’s a lot of crazy cool shit that you pretty much just get for free by using an awesome language. Congrats for making a good choice!

But, it is still a new language. It provides all the correct flex points for building incredibly powerful software, maintainable, and efficient software.

However, its newness limits the documentation available as well as the guidance provided for growing this software in a way that takes full advantage of all of these characteristics.

That’s what I aim to change. I hope to put together a book and several parts to a series that document best practices for growing an Elixir project past the usefulness of the generators and currently available blog posts.