Journey to Elixir
19 June 2023

Journey to Elixir

I had my first exposure to Elixir/Phoenix about 3 years ago. Two of the developers I work with had tried it and were excited about it enough to want to share what they had learned with the company via a lunch-and-learn. My first thought was “please, not another framework!”. But I thought I might learn something useful, so I picked up my computer and grabbed a seat. It was a “code along” talk so we started by installing Erlang. Things started out bad for me, the installation took too long and the talk had moved on to the examples, so I killed the install and sat back and watched. I saw tuples, piping and pattern matching. It all seemed quirky. I figured this would not go anywhere, so I excused myself and went for a walk. After all, I was a Rails developer and this would not help me with that. Since then I have seen a gradual change at our company from mostly Ruby/Rails work to mostly Elixir/Phoenix work.

Later, about 6 or 7 months ago, I read a blog post by a Rails consultant. He was looking for more Rails work and had reached out to a friend who had previously given him some leads. This time, his friend didn’t have any Rails leads, but said that if he knew Elixir he had more work than he could handle and would share some. He did not, but wanted to get in on this new work opportunity. So he set out to learn Elixir/Phoenix. He too had become excited about what he had discovered; tuples, piping, pattern matching and more. I realized that my attitude might be wrong and maybe I was missing something worthwhile. I decided I would take a look at it sometime in the future, but not now.

Not long after reading that blog post, one of our managers said in a company standup “I’m happy to see all the Elixir work we are doing. I feel like Elixir is where Ruby was 10+ years ago. It’s an exciting time to be an Elixir Dev!” Wow! That’s not what I ever expected to hear. I decided that I owed it to myself, and maybe my career, to take a more serious look at Elixir/Phoenix to see what I might be missing out on. After all, that kind of excitement was what drew me to Rails in the first place. Maybe there was something to this Elixir stuff. That weekend I got Elixir set up and started a basic Elixir tutorial.

A couple of weeks later the Advent of Code released its annual challenges, I decided that it would help me learn Elixir by working through the challenges. I would do this side-by-side with a corresponding Ruby solution so I could compare them and maybe the Ruby would help if I got stuck doing the Elixir solution. Here are the results of the first day’s challenge.

The Ruby code:

class CalorieCounter
  @calories = []

  def initialize
    raw_data = File.readlines('./input.txt')
    @calories = clean(raw_data)
  end

  def find_max_carried
    carried_calories = 0
    @max_calorie = 0

    @calories.each do |calorie|
      if calorie == 0
        @max_calorie = carried_calories if carried_calories > @max_calorie
        carried_calories = 0
      else
        carried_calories += calorie
      end
    end
    @max_calorie
  end

  private

  def clean(raw_data)
    clean_data = []
    raw_data.each do |row|
      clean_data << row.gsub(/\R+/, '').to_i
    end
    clean_data
  end
end

The above code is fairly simple and easy to read. It reads a data file, puts that into an array, sums them and sets the max calories carried.

The Elixir code:

defmodule CalorieCounter do

  def max_calories do
    File.read!('./data/day01.txt')
    |> String.split( "\n\n")
    |> Enum.map(&sum_calories/1)
    |> Enum.max()
  end

  defp sum_calories(calories) do
    calories
    |> String.split("\n", trim: true)
    |> Enum.map(&String.to_integer/1)
    |> Enum.sum()
  end
end

The above code is in a word, ‘less’, which is exciting. It does the exact same thing as the Ruby code, but mostly leverages Elixir built-in functions.

While both the Ruby and Elixir solutions give the same result, the way they go about it is strikingly different. There are fewer lines of code in the Elixir solution. The logic blocks I wrote in the Ruby solution are replaced by simple Elixir built in functions; where the output of each is piped into the next. It feels lighter, took less time to code and seems to run faster. I was feeling the excitement that others were talking about. I was becoming hooked.

While this was a good first impression of Elixir, it was overly simple. The real test is what can you build with it, in the real world, and what is that experience like.

My first Elixir project came about six months after hearing the manager’s announcement. And what was more exciting for me was that this project was to be in Phoenix LiveView. LiveView, for those who do not know, involves rendering HTML on the server, as Rails does. It keeps a socket connection between the browser and the server for “live” updates, like React or HotWire, but is much easier in it’s implementation.

The project started with a discovery phase involving two very senior team members, a designer and a developer. They met with the clients and went through their needs over about a week. After the project needs were understood, over the next few weeks, they made wireframes of the new website, built out the cards on the kanban board, and generated a few basic screens to make a simple, working prototype. Once the discovery was completed and the clients were in agreement, the development phase began. The team was changed. The discovery phase developer went to another project and I and another, more experienced Elixir developer came on board.

With the wireframes, kanban cards, and prototype in our hands, we did something I have never experienced before - Test Driven Development (TDD). Most projects want to do this, but things quickly break down to building features first, then making tests for them. For us, each page, menu or section of the site had a wireframe, a kanban card, and many features were in the prototype. So we started with tests before writing any code. The first test might be just to find the title, from the wireframe, on the page. The test would fail and we would add the title, the route, the template, or fix whatever the test said caused the failure until it passed. Then we added another test for another element or feature. The documents from the discovery phase freed us from most discussions of what we should make, or how it should function. We did that for the entire site. Development moved very quickly; surprising us and pleasing everyone, especially the client. It was just an overall great experience.

After that project I really wanted to build more LiveView projects. But in the consulting world, things do not always work that way, and I went on to work on another Rails project. That application had a page that needed a popup form for editing some data. For this I wanted to try something I had learned from working in LiveView. I added a modal like those that LiveView provides; wiring it up with Stimulus and Turbo in a LiveView way. It worked. So now I had come full circle. The technology that I had dismissed just a few months ago had become my new favorite tool and had been useful in my Rails work as well.

What are my take-aways from this experience. I am not going to say that you should try every new framework, language, or whatever that comes along. There is just too much of that. But do allow yourself to try new things and change your mind. There’s a saying that if you are comfortable with the skill set you have, then it is probably outdated, and you need to change. And you might just find, like I did, that you like the new thing better than what you were doing.

Related Posts

Want to learn more about the work we do?

Explore our work

Ready to start your software journey with us?

Contact Us