Understand the pin “^" operator in Elixir

Julien Corb
4 min readMay 13, 2019

--

pin-operator-shaped roman temple roof

To understand what the ^ operator does in Elixir, you have to understand what = does.

Pattern matching

In most languages, = is the assignment operator. If you want to assign the value 1 to a variable a , depending on the language, you are going to write something like a = 1 . The value of the right hand side is assigned to the value of the left hand side.

But in Elixir, = isn’t the assignment operator. it is the match operator. The match operator is at the heart of one of the most powerful feature of the elixir language: pattern matching.

Here is what pattern matching does :

  1. it matches the value on the left hand side with the value on the right hand side.
  2. if it matches and if the left hand side includes a variable, it assigns the corresponding value from the right hand side to the variable.

Therefore if we write a = 1 in elixir, we are matching the left hand side a to the right hand side 1 . As it matches, elixir assigns the value 1 to a .

Let ‘s now share an example from the elixir console (see here if you want to install elixir and see how to use the console) :

iex> [x, y, z] = [1, 2, 3]
[1, 2, 3]
iex> x
1
iex> y
2
iex> z
3

Here, elixir matches x with 1 , y with 2 and z with 3 . Each variable on the left hand side has a matching variable on the right hand side.

but if we write:

iex> [x, y, z, t] = [1, 2, 3]
** (MatchError) no match of right hand side value: [1, 2, 3]

There’s nothing that matches on the right hand side with t , so elixir returns an error.

The pin operator

Now that you understand what pattern matching is, let’s have a look at the pin ( ^ ) operator !

remember the two effect of pattern matching :

it matches the value on the left hand side with the value on the right hand side. if it matches and if the left hand side includes a variable, it assigns the corresponding value from the right hand side to the variable.

This is great but sometimes, for some reasons, I just want to make sure what I have on the left hand side matches with what I have on the right hand side, without any assignment in case I have a variable on the left hand side. In other words, I just want to compare both sides.

This is exactly what the ^ operator allows me to do : It pins the variable on its value and prevent any assignment to this variable when using pattern matching.

iex> a = 1
1
iex> ^a = 2
** (MatchError) no match of right hand side value: 2

First we pattern match a and 1 , so 1 is assigned to a . Then we pattern match a with 2 but we pinned a on its value 1 , so elixir returns an error. ^a = 2 is like if we had 1 = 2 . It does not match.

Let’s use our previous example again:

iex> [x, y, z] = [1, 2, 3]
[1, 2, 3]
iex> x
1
iex> y
2
iex> z
3
iex> [x, ^y , z] = [4, 5, 6]
** (MatchError) no match of right hand side value: [4, 5, 6]
iex> x
1
iex> y
2
iex> z
3
iex> [x, y , z] = [4, 5, 6]
[4, 5, 6]
iex> x
4
iex> y
5
iex> z
6

Here we pin y on 2, so when we try [x, ^y, z] = [4, 5, 6] , elixir returns an error because y is pinned to 2 which does not match 5. The left hand side and the right hand side do not match and there is no assignment, not even to x nor z. It’s like if we had [x, 2, z] = [4, 5, 6] .

Next we try [x, y, z] = [4, 5, 6] and this time we do not get any error: y isn’t pinned, so if there is a matching value on the right hand side, y will be assigned to it. Here, both sides match so x returns 4, y returns 5 , and z returns 6 .

Now you understand how the ^ operator works ! You should be able to use it in your project if needed. Hope you enjoy your Elixir journey as much as I do !

Thank you to @ cybrok from the Elixir Slack for his feedback that helped me improve this article.

--

--

Julien Corb

Ruby, Elixir, JS developper — Tech Addict — Beer Brewer