Hello World — Elixir

Here’s a personal favourite. Elixir is a dynamic, functional programming language built thinking about scalability and parallelism. It is built on top of Erlang, so performance wise it’s really powerful.

It is not quite as popular as other programming languages out there and it has a relatively small community due to being still young, but its capabilities are still great.

I think developers tend to favour GoLang for exploiting distributed tasks or Clojure and Scala on the functional aspect, yet Elixir seems to me like a nice place in the middle.

Some of the issues around Elixir revolve around lack of popularity for functional languages, reduced compatibility in some hostings and sometimes poor error readability when things go wrong.

This article is going to be divided into 3 sections: Installation, Basics and Capabilities.


The installation using homebrew is fairly simple. You can use

$> brew install elixir

and brew will do all the heavy lifting for you. You can test your installation using elixir --version.

Using a version manager

There are multiple version managers available for Elixir. I particularly like and use kiex. It’s really simple to use and to be fair, it’s the one I’ve had less trouble with.

To install kiex, they provide an installation script you can run from your shell

$> curl -sSL <https://raw.githubusercontent.com/taylor/kiex/master/install> | bash -s

From there you can follow the instructions if necessary. This script will install kiex in your $HOME/.kiex

Usage is fairly simple as well, you can check the available versions installed on your system with

$> kiex list
=* elixir-1.8.2
# => - current
# =* - current && default
# * - default

or generate a list of available releases for you to download with

$> kiex list known
Getting the available releases from <https://github.com/elixir-lang/elixir/releases>
Known Elixir releases:

From where you can pick the version you want to install and let kiex do it for you

$> kiex install 1.11.3

When going around project folders, you can select the Elixir version you want to use (provided it’s been installed), via kiex with

kiex use 1.8.1

There are other interesting things you can do listed in their documentation. For now, I’ll stick to the simple usage commands.


To make it easy for ourselves to start testing things out, we’ll use a really neat tool called the Elixir Interactive Console (iex — Interactive Elixir). Similarly to the ruby irb or Python interactive shell, it will allow us to test simple concepts first.

If Elixir is correctly installed, you should be able to enter the iex from your shell by typing the iex command

$> iex
Erlang/OTP 23
Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)

Once in the console we can start playing around with Elixir.

Elixir has specific data types, but you don’t have to explicitly declare them. The basic ones include

iex> 1          # integer
iex> 0x1F # integer
iex> 1.0 # float
iex> true # boolean
iex> :atom # atom / symbol
iex> "elixir" # string
iex> [1, 2, 3] # list
iex> {1, 2, 3} # tuple

These data types are pretty similar to other programming languages. So you can perform operations on them, pass them around in variables etc. There are a few important differences however, which will be mentioned towards the end of this section.

Using these data types is also pretty similar to other programming languages

# Arithmetic operations behave the same
iex> 1 + 2
iex> 5 * 5
# String interpolation behaves the same
iex(1)> string = :world
iex(2)> "hello #{string}"
"hello world"
# And you can print using the IO module
iex> IO.puts "hello world"
hello world
# Notice the return value of the method is :ok. More on that later

To perform operations on data types or variables, you will have to use the methods from its class. Take the String class for example

iex> String.upcase("hello world")
iex> String.split("foo bar")
["foo", "bar"]
iex> String.reverse("abcd")

There are however, quite a few functions that are available in the global scope

# To check whether a variable belongs to a data type
iex> is_boolean(true)
# To check if a variable is NULL
iex> is_nil("hello world")

Pattern matching

iex(1)> hello = "hello world"
"hello world"
iex(2)> hello
"hello world"

But consider the following sequence

iex(1)> hello = "hello world"
"hello world"
iex(2)> "hello world" = hello
"hello world"
iex(3)> "goodbye world" = hello
** (MatchError) no match of right hand side value: "hello world"

What happened?

It turns out that the = is actually called the match operator, or pattern matching operator. Its goal is not to simply assign values but to compare the two sides of the equation.

This is pretty useful in more complex situations, like destructuring expressions for example

iex(1)> {a, b, c} = {:hello, "world", 42}
{:hello, "world", 42}
iex(2)> a
iex(3)> b
iex(4)> c

But more interestingly when comparing specific types as a result of a particular operation.

Consider the following example

iex(1)> {:ok, result} = {:ok, 200}
{:ok, 200}
iex(2)> result
iex(3)> {:ok, result} = {:error, 401}
** (MatchError) no match of right hand side value: {:error, 401}

Notice that :ok and 200 are values being matched. When those values do not match, we have received unexpected data, and the operation will be invalid. Do the codes seem familiar to you? 200 and 401 are common http response codes, and you can use pattern matching to handle http responses in a neat manner

# Simple http request example for pattern matching response
def http_request(url) do
case HttpRequest.get(url, headers(), []) do
{:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
{:ok, %HTTPoison.Response{status_code: 401}} ->
IO.puts "[ERROR] Authentication failed."
{:ok, %HTTPoison.Response{status_code: status_code}} ->
IO.puts "Unexpected http response: #{status_code}"
{:error, %HTTPoison.Error{reason: reason}} ->
IO.puts "Unexpected error: #{reason}"

Process calls in Elixir typically return a status and the result. In the previous example you can see either the tuple {:ok, response_object} or {:error, error_object} for which we can pattern match accordingly and handle each scenario separately. The Pattern match can be as complex as you'd like.

There’s more much to talk about this complex, yet amazing programming language. I will release a series dedicated to Elixir soon.


In Elixir, all code runs inside processes, which are isolated from each other and run concurrently and communicate passing messages between each other.

These processes are quite lightweight, for which at any given time you may be running a great amount of them.

This allows for incredible fault tolerance. Processes can be restarted quite quickly without big performance implications. In fact, Elixir’s strategy for error recovery is simply killing the processes and starting it again. This is a “fail fast” strategy. Elixir developers made the design decision that letting a program fail and recover fast was a better strategy than defensive programming and trying to predict any possible error.

Additionally to standard processes, Elixir has GenServers and Supervisors. These are in charge or keeping state and monitoring other processes respectively. GenServers and Supervisors are the building blocks of server-client relationships.

In terms of parallelism, Elixir has built-in modules like the following

results = Task.Supervisor.async_stream_nolink(
(fn item -> MyApp.process_item(item) end),
[max_concurrency: 50]

In which we ask a supervisor to spawn 50 processes concurrently to deal with a list of items that need, well, processing. This is particularly useful in scenarios where we need to query external APIs or run particularly slow operations on each item.

If we have a list of 1000 items and 50 concurrent processes working on it, it only takes 20 rounds to get your results, and more importantly you can have them all combined at the end without dealing with any of the concurrency yourself.


Every programming language has a thing for which they’re good at. Elixir is great for concurrent processing and easy parallelism. There are, of course, other solutions like GoLang or if you need greater data scale, tools like Apache Spark are better suited for the job. But Elixir should be considered given its simplicity and functional approach. Remember there’s no one way to solve a problem.

Software Engineer in the UK, also tech enthusiast. Interested in problem solving and public speaking.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store