1 Introduction

Welcome! In this tutorial we are going to show you how to get started with Elixir. We will start with how to install Elixir, how to use its interactive shell, and basic data types and operators. In later chapters, we are even going to discuss more advanced subjects such as macros, protocols and other features provided by Elixir.

To see Elixir in action, check out these introductory screencasts by Dave Thomas. The first one, Nine Minutes of Elixir, provides a brief tour of the language. The second one is a 30-minute introduction to Elixir that'll help you get started with writing your first functions and creating your first processes in Elixir. Be sure to follow the next section of this guide to install Elixir on your machine and then follow along with the videos.

Keep in mind that Elixir is still in development so if at any point you receive an error message and you are not sure how to proceed, please let us know in the issues tracker. Having explanative and consistent error messages is one of the many features we aim for Elixir.

1.1 Installation

The only prerequisite for Elixir is Erlang, version R16B or later. You can find the source code for Erlang here or use one of the precompiled packages.

For Windows developers, we recommend the precompiled package. Those on the UNIX platform can probably get Erlang installed via one of the many package management tools.

After Erlang is installed, you should be able to open up the command line (or command prompt) and check the Erlang version by typing erl. You will see some information as follows:

Erlang R16B (erts-5.10.1) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Notice that depending on how you installed Erlang, it will not add Erlang binaries to your environment. Be sure to have Erlang binaries in your PATH, otherwise Elixir won't work!

After Erlang is up and running, it is time to install Elixir. You can do that via Distributions, Precompiled package or Compiling from Source.

1.1.1 Distributions

This tutorial requires Elixir v0.9.0 or later and it may be available in some distributions:

  • Homebrew for Mac OS X
    • Since Elixir requires Erlang R16B, first call brew tap homebrew/versions and then brew install erlang-r16
    • If you have a previous Erlang version installed, unlink it with brew uninstall erlang and link the new one with brew link erlang-r16
    • Update your homebrew to latest: brew update
    • Install Elixir: brew install elixir
  • Fedora 17+ and Fedora Rawhide: sudo yum -y install elixir
  • Arch Linux : Elixir is available on AUR via yaourt -S elixir

If you don't use any of the distributions above, don't worry, we also provide a precompiled package!

1.1.2 Compiling from source (Unix and MinGW)

You can download and compile Elixir in few steps. You can get the latest stable release here, unpack it and then run make inside the unpacked directory. After that, you are ready to run the elixir and iex commands from the bin directory. It is recommended that you add Elixir's bin path to your PATH environment variable to ease development:

$ export PATH="$PATH:/path/to/elixir/bin"

In case you are feeling a bit more adventurous, you can also compile from master:

$ git clone https://github.com/elixir-lang/elixir.git
$ cd elixir
$ make test

If the tests pass, you are ready to go. Otherwise, feel free to open an issue in the issues tracker on Github.

1.1.3 Precompiled package

Elixir provides a precompiled package for every release. Precompiled packages are the best option if you are developing on Windows.

After downloading and unzip-ing the package, you are ready to run the elixir and iex commands from the bin directory. It is recommended that you also add Elixir's bin path to your PATH environment variable to ease development.

1.2 Interactive mode

When you install Elixir, you will have three new executables: iex, elixir and elixirc. If you compiled Elixir from source or you are using a packaged version, you can find these inside the bin directory.

For now, let's start by running iex which stands for Interactive Elixir. In interactive mode, we can type any Elixir expression and get its result straight away. Let's warm up with some basic arithmetic expressions:

iex> 1 + 1
2
iex> 10 - 5
5
iex> 10 / 2
5.0

Notice 10 / 2 returned a float 5.0 instead of an integer. This is expected. In Elixir the operator / always returns a float. In case you want to do integer division or get the division remainder, you can invoke the div and rem functions:

iex> div(10, 2)
5
iex> div 10, 2
5
iex> rem 10, 3
1

In the example above, we called two functions called div and rem. Notice that parentheses are not required in order to invoke a function. We are going to discuss more about it later. Let's move forward and see which other data types we have in Elixir:

1.3 Basic types

Some basic types are:

iex> 1          # integer
iex> 0x1F       # integer
iex> 1.0        # float
iex> :atom      # atom / symbol
iex> {1,2,3}    # tuple
iex> [1,2,3]    # list
iex> <<1,2,3>>  # binary

Elixir by default provides many functions to work on those types:

iex> size { 1, 2, 3 }
3

iex> length [ 1, 2, 3 ]
3

Elixir also provides functions (note the dot between the variable and arguments when calling a function):

# function
iex> x = fn(a, b) -> a + b end
#Fun<erl_eval.12.111823515>
iex> x.(1, 2)
3

Elixir also supports strings and they are all encoded in UTF-8:

iex> "hellö"
"hellö"

Strings support interpolation too:

iex> name = "world"
iex> "hello #{name}"
"hello world"

At the end of the day, strings are nothing more than binaries. We can check it using the is_binary function:

iex> is_binary("hello")
true

Note a single-quoted expression in Elixir is a char list and it is not the same as a double-quoted one:

iex> is_binary('hello')
false

We will go into more details about char lists in the next chapter. Finally, Elixir also provides true and false as booleans:

iex> true
true
iex> is_boolean false
true

Booleans are represented internally as atoms:

iex> is_atom(true)
true

Elixir also provides Port, References and PIDs as data types (usually used in process communication) but they are out of the scope of a getting started tutorial. For now, let's take a look at the basic operators in Elixir before we move on to the next chapter.

1.4 Operators

As we saw earlier, Elixir provides +, -, *, / as arithmetic operators.

Elixir also provides ++ and -- to manipulate lists:

iex> [1,2,3] ++ [4,5,6]
[1,2,3,4,5,6]
iex> [1,2,3] -- [2]
[1,3]

String concatenation is done via <>:

iex> "foo" <> "bar"
"foobar"

Elixir also provides three boolean operators: or, and and not. These operators are strict in the sense they expect a boolean (true or false) as their first argument:

iex> true and true
true
iex> false or is_atom(:example)
true

Giving a non-boolean will raise an exception:

iex> 1 and true
** (ArgumentError) argument error

or and and are short-circuit operators. They just execute the right side in case the left side is not enough to determine the result:

iex> false and error("This error will never be raised")
false

iex> true or error("This error will never be raised")
true

Note: If you are an Erlang developer, and and or in Elixir actually map to the andalso and orelse operators in Erlang.

Besides those boolean operators, Elixir also provides ||, && and ! which accept arguments of any type. For these operators, all values except false and nil will evaluate to true:

# or
iex> 1 || true
1
iex> false || 11
11

# and
iex> nil && 13
nil
iex> true && 17
17

# !
iex> !true
false
iex> !1
false
iex> !nil
true

As a rule of thumb, use and, or and not when you are expecting a booleans. If any of the arguments are non-booleans, use &&, || and !.

Elixir also provides ==, !=, ===, !==, <=, >=, < and > as comparison operators:

iex> 1 == 1
true
iex> 1 != 2
true
iex> 1 < 2
true

The difference between == and === is that the latter is more strict when comparing integers and floats:

iex> 1 == 1.0
true
iex> 1 === 1.0
false

In Elixir, we can compare two different data types:

iex> 1 < :atom
true

The reason we can compare different data types is for pragmatism. Sorting algorithms don't need to worry about different data types in order to sort. The overall sorting order is defined below:

number < atom < reference < functions < port < pid < tuple < list < bit string

You actually don't need to memorize this ordering, but it is important just to know an order exists.

Well, that is it for the introduction. In the next chapter, we are going to discuss some basic functions, data types conversions and a bit of control-flow.