Skip to content

Learning Elixir: 1 year later

One year ago I started learning Elixir because I saw great potential. This is my retrospective, looking back on my journey so far with Elixir.

TLDR - summary

During the last year I liked functional programming, the Elixir language, the community, parallel tests, the fast workflow, the dependency management and the powerful platform. I had troubles with Erlangs cryptic error messages, IDE support, code density and deployments. My excitement for Elixir is still as high!

What I did in 2017

Before reflecting on how I liked things in Elixir land, I like to summarize what I actually did.

Books

After watching screencast series and doing exercises mentioned in the blog post one year ago I have read the following books:

Out of these books I found Elixir in Action the most challenging (in a good way) and inspiring. In a way that's also because it was one of the first books I've read. Which means that some content was repeated in other books. For GraphQL specifically I really liked what's already available in "Craft GraphQL APIs in Elixir with Absinthe (beta)".

Talks

Playlists of Elixir conference talks I watched:

Side projects

My preferred way to learn new technologies is to solve problems that I see.

This brings two things: having a solution to a problem and learning about different aspects of a technology. These aspects are for me: development speed, testability, maintainability, reliability and observability in production, community support, tooling support and performance.

Estimator

The first side-project was about solving a problem I saw at work. I saw a need for a Planning Poker tool that integrates with Jira. The tool called Estimator is used since June regularly, about every 1-2 weeks by two teams. Here is a demo:


What I did during this side-project:

  • Soft realtime synchronisation of data via websockets
  • Authentication via Github
  • Deploying to Heroku
  • Database usage via Ecto: schemas, migrations, queries
  • Using external APIs (Jira)
  • Caching data across requests
  • Continuous integration setup
  • A little bit about automated testing

The source code is on Github. Read more about it in the Estimator blog post.

Picape

The second side-project is a tool to make it easier to order ingredients at a home delivery supermarket. Picape holds a mapping of recipes and their ingredients to products from a supermarket. For the last 3 months, we are using the tool twice a week. Here is a demo:


What I did during this side-project:

  • Building a GraphQL API in Elixir
  • Automated parallel testing of GraphQL, databases and websockets
  • Structuring an application using Phoenix Contexts
  • Deploying on a VPS (virtual private server) with git push
  • Integrating Sentry for error tracking and Timber for logs
  • Code coverage with Codecov

The source code is on Github. Read more about it in the Picape blog post.

What I liked

There are many small details that I liked. When looking at the whole year I would mention these points in particular:

Functional programming

Before learning Elixir, I have applied functional programming principles in Javascript with Lodash and Ramda. It turned out to be mind bending when these principles are the only ones available – like in Elixir. I'm happy to have gone "through the pain". In the beginning the syntax looked strange and confusing to me. But after few days, when the concepts began to "click", I started to see the beauty of it.

Elixir language

Once I was used to the pipeline operator |>, pattern matching and the with statement I started to miss it in other languages.

The with statement I find particularly nice because it simplifies error handling in a sequence of function calls. There is a great explanation and example on StackOverflow.

Community

I was hanging out in Slack channels, read blog posts and some forums. What I consistently noticed is how friendly, helpful and open the community is. I'm not saying that other communities are less good. Just that Elixirs community is at least as good.

Parallel tests

My phone has 6 CPU cores. Looking at the increase of cores in devices over the last years makes parallelism in programming more important. One area where leveraging parallelism is great, is running automated tests in Elixir. Especially integration tests with databases.

As projects grow, their automated tests get slower. It takes a constant effort to keep the test times low, to be able to move fast. This is still the case with Elixir, but using all available resources without having developers caring about it can minimize this effort.

Fast workflow

Developing in Elixir using the web framework Phoenix feels very similar to using PHP. Code changes don't need a server restart like in NodeJS. I like how live reloading on code changes comes out of the box, making the developer experience even better.

Dependency management

Using Mix with hex to install and update library dependencies is a pleasure. It is fast, customizable, reliable and gives helpful instructions in case of conflicts. Especially compared to Composer, a PHP dependency manager, I found this a much better experience. Don't get me wrong, I still think Composer is a great software and transformed the PHP world a few years ago.

Powerful Platform

I'm repeating a bit what I mentioned last year but I still want to stress the importance of running Erlang under the hood. The following comparison shows what I mean:

Source

All components are solid. Apart from a PostgreSQL database I had no infrastructure setup. This is great for development and production simplicity. Note that you can still use software like Redis, Memcached, Cron etc if needed. Some examples:

ConCache.get_or_store(:bucket, key, fn() -> compute(key) end)

What I didn't like

Like with everything, there are some cons. Or I didn't understand it well enough yet.

Erlang's cryptic error messages

I have to say that Elixirs error messages are very helpful. More helpful compared to PHP and Javascript. However, Elixir runs on Erlang. Those messages can be sometimes a bit cryptic. Unfortunately (for this blog post) I can't see my production error messages anymore. The last error is too long ago.

Searching for this reveals some error messages like (ArithmeticError) bad argument in arithmetic expression. Those I find hard to make sense of. I like that Elixir core developers are contributing to Erlang to improve this: example.

IDE support

I've used many editors like VIM, Atom and VSCode. When working with PHP I'm happy with PHPStorm and the features from WebStorm with support for Javascript and other web technologies. The Elixir language support is not yet on par. The Elixir plugin for IntelliJ and Elixir language server are awesome efforts to improve this though.

Code Density

Elixir is a very nice language and it is very expressive. This expressiveness means that code can get dense. Especially when pattern matching is new to someone.

To not step on anyones toes, let's look at some code I wrote last year. It's an exercise on exercism.io. A function that returns whether the first list is a sublist or a superlist of a second list, and if not whether it is equal or unequal to the second list. Here my solution using pattern matching on function definitions and recursion. This is performant but I find it also hard to see what's happening.

I felt it was too hard to read for my future self and picked up an idea from another solution for this problem not using recursion. This is much slower but in my opinion easier to read.

My point here is: I like the expressiveness of Elixir. When trying to pack too much information in a piece of code it can become too dense though.

Deployments

Deployments could be better supported out of the box. The best experience was deploying to Heroku, this works great.

For Picape I could not use Heroku however because I wanted to separate the frontend (running on NodeJS, using next.js) and backend (Elixir/Erlang process) but keep the simplicity of one repository. I ended up with starting a NodeJS process when starting Elixir/Erlang. On Heroku I had issues opening multiple ports and get the forwarding working.

Deploying to my VPS was easy but I had to do some scripting and find out how to restart the Elixir process. This is by no means a zero downtime deployment. I would love to learn a way how to do this properly.

Summarizing

I'm very happy to have learned Elixir and I'm planning to learn more. I think it helps me to become a better developer. It's awesome to see that so many great people are working on Elixir and improving it.

A few upcoming things I'm excited about: Elixir formatter, property-based testing, an abstraction for monitoring Phoenix and improved deployment tools.

© 2022 by Adrian Philipp