Know how the equals operator actually works
This is one of the things I love about Elixir; it is one of those very powerful features that I use every day and that I miss when I use Python or other programming languages.
The assignment operator “=” is an equivalence operator. In Elixir, we make a variable equal to a value and vice versa. Let’s see an example: assigning the variable x the value of “hello.”
Thus we can make an evaluation of the value with the variable so that it returns the original value.
When we evaluate the variable with a value other than “hello,” it will give us a MatchError error. The only possible way it can work is if the variable is on the left side of the operation. However, this overwrites our original variable.
Previously we talked about several data structures, the tuples. We said they were similar to lists, but they are stored differently in memory. The type of structure is very important talking about data decomposition with Pattern Matching. We will see it shortly. First, let’s see an example of the destructuring of a tuple.
If we have three elements in our tuple, we can initialize a variable for each of these elements in a very simple way:
x, we have the
atom :hello, and in
atom :world , and so on.
This works by matching the number of variables to the number of values. If we have fewer values than variables, we will get a MatchError error.
We cannot assign variables in this way when the type of structure is different, For example, comparing tuples with a list.
Many times, in Phoenix, we have, as a result of operations, a tuple where the first value is an atom of
type :ok (or
:error) and the second value is the result (or the reason for the error), and these atoms have to match on both sides of the
For the destructuring of lists, we can extract the first element (or the last elements) in a similar, very simple way: assigning a variable called
head to the first element, then placing the operator
| and placing a variable where the rest of the elements of the list will be.
We can destructure several elements, not only the first one. Let’s see an example where we extract the first two elements:
An empty list cannot be assigned to two variables because there are no matching elements.
And this is the same reason why the function
tl/1) does not work with an empty list. Returning an error of type
ArgumentError in the case of functions or a MatchError as in the previous case.
Let’s say we have a list to which we want to add an element at the beginning. What we could do is use the
++ operator between the lists. However, we can also use Pattern Matching for this.
Or, as I said, use the
++ operator. However, we would have to put our element in a new list.
Variables in Elixir can be reassigned or overwritten. Sometimes, this is not what we want; sometimes, what we want is to do a Pattern Matching. Let’s see it more clearly with the example at the beginning of this post.
If we want to see if
x is equivalent to another value, we will have to make use of the pin operator. This is so it can be matched instead of reassigned.
This is very useful when we already have an initialized variable and we want to know if the result of an operation has that value to assign a new variable to the rest of the operation. Here’s an example:
As there is a Match, now we have in our variable
x the string “this is a result from another operation.” If there is no Match, we get an error of type MatchError, and our variable
x is not assigned anything.
This happens because we are comparing
:nope atoms, but they are not the same.
We are often not interested in saving the result of an operation in a variable. However, due to the number of elements that the result returns, we have to place a variable so the Pattern Matching works correctly.
For this, we use the
_ that represents a value that is going to be ignored in the pattern. Let’s see an example with the previous code.
If we don’t want to use the string that gives us the right side of the assignment, we still have to place a variable for the Pattern Matching to work. The following does not work:
So we decided to place it as follows:
As you can see, Pattern Matching is a very elegant tool for extracting information. It provides versatility and, in my opinion, it is much faster to work this way. If you know JS, you will surely be familiar with this way of declaring variables.
In the next post, we will see the different control structures in Elixir and how they relate to Pattern Matching.
Here’s a link to the first part of this series.