Part 1 — The basics: What is Elixir and its types
It is a dynamic and functional language designed to build scalable and maintainable applications.
It runs on top of the Erlang virtual machine, known for running low-latency, distributed, and fault-tolerant systems.
In the Erlang virtual machine, all code runs in small concurrent processes. Each of these processes contains its own state. These processes talk to each other through messages.
It is a general-purpose language used in web development, embedded software, data management, and multimedia processing, as well as a wide range of industries.
The Erlang ecosystem is vast, running Elixir, LFE, Alpaca, Prolog, Luerl (Lua).
Several companies use Elixir in production, such as Heroku, Discord, and change.org, among others. Apple and Adobe also use Elixir in some of their APIs.
For macOS, it is very easy using Homebrew:
For Ubuntu or Debian, it is also very simple:
Once Elixir is installed, we can use its command line or the elixir interactive console just by writing iex.
It works perfectly as a calculator. However, other tools can make it easier for us to learn this programming language.
It is quite useful for prototyping code solutions, as is Jupyter with Python. There are many ways to install Livebook on Mac. The files are already packaged in a dmg, so just download them and move it to your applications folder.
Installing it using Elixir is very easy too. Elixir comes with a package manager, like npm or pip, called mix (and for Erlang, there is hex).
A great thing about Livebook is that we can add connections to databases and graphs in cells other than code cells. They are called smart cells.
Let’s see some examples with the basic types of Elixir:
Additions, subtractions, and multiplications are exactly the same as in other programming languages; however, divisions always return a float. To avoid this, we use a Kernel module function (which is self-imported) called div/2.
As in Ruby, in functions, parentheses are optional, for example:
Functions are stored in modules. To identify and document them, the anatomy is as follows:
The only module that is self-importing, as I already mentioned, is the Kernel module.
Inside Livebook, some helpers allow us to see the documentation in a very intuitive and nice way. We place the name of the module, and we hover with the mouse. This brings us not only the documentation but also quite good examples.
These are variables whose value is the same as the variable name. Here’s some example code:
Several operations can be done with atoms, for example, comparisons.
In Elixir and Erlang, atoms usually express the status of an operation, most commonly with
Boolean values are atoms, but for convenience, they are handled without the initial colon.
Elixir has a construct called aliases that start with capital letters. These are also atoms, generally used to name modules.
Atoms can be interpolated into strings. It is important to mention that strings always use double quotes, as in many programming languages.
To handle strings, we use the module called String. For example, they may help us know the length of a string and several interesting functions such as uppercase.
The anonymous functions are delimited by the keywords
The way to execute that function is by means of a dot and, in parentheses, the arguments.
As we did for the booleans, we can see if our variable add is a function by means of another function called
We can also see how many arguments the function receives. To validate the number of arguments, we pass it the following:
They can access variables within the scope of the original function. For example:
A function can not redefine a variable that is not within the scope of the same function, let’s make an anonymous function that does not receive any parameter, and we execute it in the same line.
This returns the value of “hello” (and a warning because we are not using the variable). We can add an underscore to get rid of this warning.
If outside the scope of the function, we initialize the variable with another value, and we will not modify the variable’s value outside the function scope.
Elixir uses brackets to specify a list. Here’s an example:
There are functions within Kernel that let us know things about our lists. The code may look like this:
To concatenate two lists, we use the
++ operator, so we have the following:
We can also subtract a list from another list. That can look like this:
However, this only removes the first items that are displayed in the list. For example:
returns to us:
The operators on the lists in Elixir always return a new list. That is, they do not modify the existing list, the data structures in Elixir are immutable.
We can access the first elements by means of a function called head and tail.
Then we will see how to do the same but with pattern matching. This is a solution that I love and that allows me to work more efficiently with Elixir. It is genius, and it is very similar to JS restructuring.
Tuples are structures like lists. However, they are stored contiguously in memory, so they are much faster than lists. The
put_elem/3 function returns a new tuple with a new element at a given position.
More operators and booleans
The operations with
or are strict. That is to say, they only evaluate boolean values. However,
|| evaluate the complete expression. Let’s see an example below:
&& y ||
Used for truthy and falsie values
In Elixir, we can compare different types of data using the
> operators. The reason for this is purely pragmatic, so Elixir’s internal algorithms don’t care about the different types of data when ordering them. The order is as follows:
In the next installment, we will look at pattern matching, Elixir’s cool tool.