Codescrum has been using this programming language on a couple of projects, but it is still a strange language in the market and still a little unknown, so in this post, we are going to explore Elixir from the beginning and tell you how we work with it.
What is Elixir?
We cannot talk about Elixir without mentioning Erlang, so we will start this post in the eighties when the development of telecommunication services grew, and the companies needed to offer communication services without any interruption, concurrency, or fault tolerance. Ericsson created an Open Telecom Platform (OTP) called Erlang, and then made it Open Source in the nineties, and we used its advantages to develop other languages and tools.
Elixir is built on top of Erlang’s VM, called BEAM, which compiles to Erlang’s bytecode. Elixir’s syntax looks like Ruby, so if you have already programmed in Ruby, the syntax will feel familiar. Elixir can use dynamic typing by default, or static typing, using typespecs’ built-in functionality when building critical systems.
In the Elixir ecosystem, we found Phoenix, an MVC web framework. Despite Elixir and Phoenix not being as mature as other languages, like Ruby or Python, or frameworks like Ruby on Rails or Django (which has just had ten years in the market), they can solve concurrency and scalability problems in web services. So we took the opportunity to use it in our web projects.
Introduction to Elixir
First of all, we need to install Elixir and Erlang. We use the asdf tool (yes, like the first four letters on the keyboard), which is a manager version for Elixir, like pyenv for Python or rbenv for Ruby. These are the steps taken for a MacOS installation, using the GIT method over a zsh shell:
- git clone https://github.com/asdf-vm/asdf.git ~/.asdf — branch v0.8.0
- echo -e ‘\n. $HOME/.asdf/asdf.sh’ >> ~/.zshrc
- echo -e ‘\n. $HOME/.asdf/completions/asdf.bash’ >> ~/.zshrc
- We reload the shell, and then print out the asdf version:
- asdf — version (which must display something like v0.8.0-c6145d0)
- If you want to get updates run the asdf update
Cool, we then continue with the installation of Elixir/Erlang. To do this, you will need to read the information in this link about Compatibility between Elixir and Erlang/OTP, which tells you about the dependency versions you must install. asdf allows you to manage several programming languages, so we need to specify which of them we are going to use through plugins:
- asdf plugin-add erlang
- asdf plugin-add elixir
- asdf plugin list
- asdf list-all elixir (to display all elixir versions available)
- asdf list-all erlang (to display all erlang versions available)
We will use Elixir 1.9, the last stable version. Let’s install it via asdf, but remember to read the compatibility table mentioned above:
- asdf install erlang 184.108.40.206 (This step take a while)
- asdf install elixir 1.9.4
- Let’s check if the installation was correct:
- Finally, let’s check our Elixir installed version:
Now, we are going to create a new Elixir project. To do this, we use the mix tool:
- mix the new codescrum_elixir
- cd codescrum_elixir
- git init
- mix test
*If everything is going ok, then you will get a message like this:
- Now, we need to set the Elixir/Erlang versions for this project. In the project folder, execute the following commands:
- These commands will create the .tool-versions file where we will save the exact versions used in this project.
Now let’s check the structure of the project so far:
Then, let’s add some code to write a hangman game. In the lib folder, we are going to add the code to read a text plain file where we will put the words to guess:
In Elixir, classes or objects concepts don’t exist; we have modules and functions to organize our application, which is all we need. So, in the code above, we have a module called ManageFiles, which contains a function called read_file with one parameter. As you can see, the syntax is very similar to Ruby one. The module starts with an uppercase letter and is usually written in CamelCase style.
As we mentioned before, Elixir uses dynamic typing, so we do not have to declare a variable type. Like Ruby’s symbols, Elixir uses atoms. These are a type of variable where the name is its own value (you can see it as :ok named in the code above). Atoms are immutables, meaning that the same helium atom is a helium atom anywhere in the universe, so the :ok atom is the same in the entire application. In the third line, we also have something called pattern matching. This is the Elixir way to retrieve some particular information from complex data types, such as lists and tuples, and the assignment expression is just the simplest form of pattern matching.
Popular Programming Languages to Build your E-commerce Website
After thinking about this topic, we decided not to name this blog the best languages to build your e-commerce website…
The symbol |> denotes a pipe operator, and it is similar to using pipes in Linux. So in the 4th line, the value of the content variable, goes through the split function located in the String module and splits the string, according to the given parameters and the result, which is a list (linked lists) that is saved in the word_list variable. The 5th line randomly picks out one element of the word_list and returns it (there is no explicit return in Elixir).
It looks cool, but we need to know that this piece of code is working, so we are going to prove this. Let’s execute the Elixir Interactive Shell (iex) to load the code and check what happens. First, run the iex command in your terminal, in the project folder:
This command will open the interactive shell, where you will see this prompt:
Then, you are ready to call the functions and prove them. So, let’s prove our code:
Bear in mind that the words.txt file must be in the root directory of the project to be located; otherwise, put in the relative path. The content of this file is just one word per line.
At the iex shell, you can find some help for almost all the modules and operators. For instance, if you want to know more about the pipe operator, then type:
The /2 symbol is called the function Arity, which is the number of arguments a function takes. If a function doesn’t take any argument, then its arity would be /0. Try these expressions in the Interactive shell, and see what happens:
To exit from the iex shell, type System.halt or press CTRL+G or CTRL+\ or press CTRL+C twice.
Another way to prove that our code is the correct one is by doing unit tests. So, let’s code our test. In the test folder, create a mix file (.exs) called manage_files_test.exs. The code is the following:
After defining the test module, we need to tell Elixir which unit test framework is going to be used. In this case, we’ll use ExUnit, which is Elixir’s official one, and shipped with Elixir, so we don’t have to install anything else.
Then, we write our test. In this case, we will use the falsy and truthy values, where the atoms nil and false are treated as falsy values, and everything else is treated as a truthy value. So, we can validate whether the read_file function returns something by using short-circuiting logical boolean operators. We could also use the boolean data type only:
Now, we can run the test:
And, if everything is OK, we have got an output like this:
Now, in the hangman_game.ex file, we will put the logic of the game. Let’s start with this piece of code:
ManageGrid is a module to create, paint (print out on screen), and fill the board. You can see the complete code on the Github repository. We have seen the ManageFiles module before, and we use it to get a word to guess. Then we call the play/2 function by passing two parameters: the board and the word to guess (Arity two):
Here we have an Elixir data structure called struct. This type of structure allows us to save information during the execution of the entire application. The main difference with maps is immutability, i.e. we can predefine some fields. In our case, this structure stores the following information:
In another file, this struct is called guess.ex, which contains the module called HangMan.Guess with the fields guess_word initialized in null and attempts initialized in 6.
In the play function, we also have the while function, which is a recursive function to control the game’s flow. In Elixir, there is not the while loop that we know in Python or Ruby, as it uses recursive functions:
As you will notice, the name of the function can be changed for whatever you want to. We use that name just for convention. The function is called recursively until the base condition is accomplished. In this case, the base condition is when the first parameter is zero; the rest of the parameters do not matter. The base case then returns the :ok atom to indicate that everything is correct. The entire code can be found on the Github repository.
Finally, let’s run the game:
And you have got something like this:
What we use Elixir for
A Codescrum project related to Elixir was built for an asbestos removal company whose solution had three components: an API service, a frontend in ReactJS, and a mobile application. The API service was made in Elixir using the Phoenix web framework and a GraphQL implementation by using Absinthe, the GraphQL toolkit for Elixir.
Resources to learn Elixir
Here are some tutorials and courses to get you started with Elixir and its web framework Phoenix:
- How to Manage Elixir versions on Mac or Linux: https://medium.com/juq/how-to-manage-elixir-versions-on-mac-or-linux-getting-started-with-elixir-12308e7b6451
- The Complete Elixir and Phoenix Bootcamp (Udemy): https://www.udemy.com/course/the-complete-elixir-and-phoenix-bootcamp-and-tutorial/
- Awesome Elixir (Resources compilation): https://github.com/h4cc/awesome-elixir
- Learn with Me: Elixir:https://inquisitivedeveloper.com/tag/lwm-elixir/
- Elixir school (translated into many languages): https://elixirschool.com/en/
- There are many exercises to be solved using Elixir that has automated mentoring: https://exercism.io/my/tracks/elixir
- Alchemist Camp (Learn Elixir and Phoenix by building things): https://alchemist.camp/episodes
- Elixir tips: https://github.com/blackode/elixir-tips
- Elixir documentation: https://elixir-lang.org/docs.html
GitHub repository. The code of the hangman project described above has been made available in the following repository: https://github.com/edycop/elixir_hangman_game
Thank you for reading!