10 Things I learned about Elixir/Phoenix (as a Rubyist) while building my first Phoenix app

by Thibault - December 5, 2016

As explained in this post, I made the switch from a slow Wordpress website to a blazing fast application built with Elixir and Phoenix. Now, I want to share the 10 things I learned about these technologies as a Rubyist.

1. Functional Programming

Elixir is a functional language, which is quite a change when coming from the object-oriented Ruby where everything is an object.
But what does it mean exactly?

If you don’t know, functional programming is a programming paradigm. The principal characteristic of this paradigm is the absence of side effects when calling a method. Most features of the Elixir language (immutable data, pattern matching, first-class functions and more) can be derived from the desire to prevent side-effects, as can be expected from a functional language.

Functional Programming is a wide and interesting topic, one I’m not comfortable enough explaining. But if you want to take a closer look, I can recommend this article on Medium.

2. Immutability

The fact that data are immutable is a big change from Ruby. If you add an element to a list in Elixir, you won’t be getting back the same list - a new one will have been created with the added element. However, a variable can be rebinded, which means you can change which data structure the variable points to/references in memory.

x = {} # x points to the data {}
x[:one] = "two" # x still points to the same data,
# but the data has been modified

It also means you cannot change data in loops; instead, map or reduce should be used. It’s also a good example of how functions don’t have side-effects and won’t change the state of the program.

a = 0
Enum.each [1, 2, 3, 4], fn number ->
# We are not changing a, just creating new variables
# limited to the scope of this anonymous function
a = a + number
end
# Therefore a didn't change
IO.puts a # => 0

This is easily fixed with reduce - we can tell Elixir to calculate the sum using an accumulator (acc).

The property of immutability has a number of advantages like data consistency and simpler concurrent programming (no need for locks!). It also makes it easier to reason about the code since functions are just about transforming their inputs into outputs, and not changing state.

3. Pattern Matching

I love pattern matching! I’m still learning all the intricacies, but it’s super useful to implement guard clauses (for example).
Whereas in Ruby, you might do something like this:

4. Supervisors and running stuff in the background

If you’re used to working with Ruby on Rails, you know that the right way to run long tasks (like sending a bunch of emails or generating a report) is to create a background job with Sidekiq or Resque.

With Phoenix (thanks to Elixir&Erlang), there is absolutely no need for that - instead,concurrent processes (Elixir processes, not OS processes) can be spawned with 1 line of code (spawn(fn -> 2 * 2 end)).

In order to manage these processes, Elixir provides the Supervisor module.

When generating a new Phoenix application, you will have the following supervisor configuration:

Instead, you can just pipe the output of each function and send it as the first argument of the following one with the pipe operator!

[1, [2], 3] |> List.flatten |> Enum.map(fn x -> x * 2 end)

This example was taken from the Elixir documentation. I was lacking the imagination to find an example…

6. Phoenix doesn’t have much hidden magic

There is much less magic in Phoenix than there is in Rails. One of the things you really need to understand is the Plug specification. In Phoenix, the entire HTTP layer is handled internally by a bunch of plugs (note that you can easily add your own!)

Each one of these plugs will receive the request object (conn) and transform it.

7. You need to learn how Brunch works

The Phoenix team decided to use an existing build tool for the assets, which is not a bad idea. They went with brunch.io, which is pretty simple and easy to use, as long as you go through their documentation.

8. Huge lack of tutorials

There is still a huge lack of tutorials and articles on Elixir and Phoenix. I had some issues for which I wasn’t able to find any help, and had to spend a lot of time figuring on my own. I’m planning to write some stuff about them to fill the hole.

9. edeliver and exrm/distillery for deployments?

The commonly accepted way to deploy Phoenix applications is with edeliver and either exrm or distillery. edeliver lets us perform hot-code upgrades which is a cool way to upgrade your application without restarting it.

However, I was disappointed by how slow the deployment was. Maybe I did something wrong, but the generated release would take hours to get copied to the production server…

So instead, I decided to go with Dokku and I’m quite happy with it, even if I don’t have hot-code upgrades!

10. Frameworks should have unique name.

Alright, this last point is a bit of a joke - don’t take it too seriously. I really had this issue with Rails ,but it happened to me more than once with Phoenix: there are too many things named Phoenix!

I can’t tell how often I searched for something in Google using “phoenix” and my query and received results about Apache Phoenix or the city of Phoenix.

Phoenix is not unique enough :’)

The End

I still have many, many things to learn, but I just wanted to share some of the first things I’ve encountered in the past weeks. I will be writing more on my experience with Elixir and Phoenix shortly, so don’t forget to subscribe to the newsletter or the RSS feed.

I’m still a beginner in Elixir so all the information in this article might not be 100% accurate. If you find anything wrong, please leave a comment to let me know.