Learn Elixir with a Rubyist, episode I


Your first Elixir code, Pipe Operator and Pattern Matching!

If you have been programming Ruby for a while you probably already heard about Elixir, you might even know José Valim, a great Rails contributor and creator of Elixir, but you might have never tried it. I know it’s hard to stop whatever you’re doing and try to get a sense of Elixir by checking a ton of docs, articles and videos. But fear no more! This is the first of a series of, short-bar-like-conversations, posts aimed to help you to wrap your head around Elixir, understand why it’s a big deal and how it works.

Install Elixir

Elixir is a dynamic, functional and compiled language designed on top of a thirty years old virtual machine, called Erlang Virtual Machine, developed by Ericson, they also developed the language that runs on it, called Erlang.

Start by installing Elixir, you can check on how to do it on Elixir website, but if you’re on a mac use homebrew, it should be the fastest solution. While you grab a nice beer and bear with me.

Functional Programming

Keep in mind elixir is a functional language. You are probably curious to know what this means, so I’ll give you the really short version. This means it expects you to follow some rules that might feel weird in the beginning but will enable you to run concurrent code, have it more organized and take advantage of Elixir main features.

In practical terms, let’s stick with one simple rule for now:

Do not override any variable.

Here is a comparisons between Ruby and Elixir code, now following this simple rule:

Ruby code:

# Pretty usual Ruby code, but definitely not functional
# because it changes the value of variable indexes,
# by appending a number into it
indexes = [1, 2, 3]
indexes << 4
indexes # => [1, 2, 3, 4]

Elixir code:

# This looks functional, because we are following our
# simple rule so far, not overriding indexes variable, but
# creating a new one instead
indexes = [1, 2, 3]
new_indexes = indexes ++ [4]

Simple right? Don’t worry it’ll get more complex then this on the next posts.

First code from Ruby to Elixir

Checkout this Ruby code, pretty usual silly stuf

Ruby code:


# Increments 1 to n# Increments 1 to n

 def inc(n)
   n + 1  n + 1
 end

# Decrements 1 to n# Decrements 1 to n
def dec(n)
   n - 1  n - 1
end

# Multiply n by 2# Multiply n by 2

def double(n)
   n * 2  n * 2
end

# This is not really easy to understand, # This is not really easy to understand, 
# chaining methods can become something # chaining methods can become something 
# hard to maintain because they are called # hard to maintain because they are called 
# in the reverse order than you read

double(dec(inc(1)))

# You could also try something different, like this, 
# but looks as bad as the first option

x = 1
_inc = inc(x)
_dec = dec(_inc)
_double = double(_dec)

Elixir code:

def inc(x), do: x + 1
def dec(x), do: x - 1
def double(x), do: x * 2

# And that’s how you would call it, it’s way easier to understand
# not only because of the syntax itself but because it follows 
# and execute the functions on the same order you are used to read
1 |> inc |> dec |> double

The Pipe Operator

By now you must have realized what |>, known as pipe operator, does. It gets the result of the the operation before it and passes it as the first argument of the function after it.

number = 1
_int = int(number)
_dec = dec(_int)

# is the same as bellow, the result of whatever is 
# before the pipe operator is passed through as the 
# first argument of the function after it

_dec = 1 |> int |> dec

Pattern Matching and Match Operator

Another great feature of Elixir is pattern matching, which does exactly what it says, it match values over patterns, fun fact, that’s exactly what regular math would expect when using the = symbol, known as match operator.

Let’s check some Ruby examples:

# This works pretty well, defines a variable x with 
# the integer 12 as its value
x = 12

# But this doesn’t work, because Ruby doesn’t 
# have a default support to pattern match
12 = x
# SyntaxError: (irb):1: syntax error, unexpected '=', expecting end-of-input

Despite of not working on Ruby, the same code would work in Elixir, by using the equal to equilibrate both sides of the equation, trying to check for matching patterns, check out the example bellow:

# So far so good
x = 12

# Here the code is valid, because x is 12 already,
# thanks to the line above, so the equation is 
# equilibrated, it’s basically stating 12 = 12
12 = x

# This line fails, because of the same reason the 
# one above works, x is defined as 12 already, so
# this equations is basically stating 21 = 12
# which doesn’t match into any pattern.
21 = x
** (MatchError) no match of right hand side value: 12

It seems silly but it can get way more interesting than this, check it out:

# Because of pattern matching you can define variables
# by matching it with patterns from both sides of the equation
[a, b, c] = [5, 9, 13]
IO.puts(a) # => 5
IO.puts(b) # => 9
IO.puts(c) # => 13

This concept gets even better when applied to functions, but that’s something we are going to discuss on our next chapter, for now I think this is a good initial hands-on introduction into elixir.

What’s Next?

This is the first of a series of posts around Elixir, it’s features and how to use it, it’s aimed to help mostly Ruby developers trying to understand it, and it’s supposed to sounds like short-bar-like-conversations, if you liked please let me know on the comments bellow and over twitter.