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, basic data types and operators. In later chapters, we are 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 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.

PeepCode also has a two hour video with José Valim called Meet Elixir.

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 in Elixir.

1.1 Installation

The only prerequisite for Elixir is Erlang, version R16B or later, which can be easily installed with Precompiled packages. In case you want to install it directly from source, it can be found on the Erlang website or by following the excellent tutorial available in the Riak documentation.

For Windows developers, we recommend the precompiled packages. Those on a 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.12.4 or later and it may be available in some distributions:

  • Homebrew for Mac OS X
    • Update your homebrew to latest with brew update
    • Install Elixir: brew install elixir
  • Fedora 17+ and Fedora Rawhide
    • sudo yum -y install elixir
  • Arch Linux (on AUR)
    • yaourt -S elixir
  • openSUSE (and SLES 11 SP3+)
    • Add Erlang devel repo with zypper ar -f obs://devel:languages:erlang/ erlang
    • Install Elixir: zypper in elixir
  • Gentoo
    • emerge --ask dev-lang/elixir
  • Chocolatey for Windows
    • cinst elixir

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

1.1.2 Precompiled package

Elixir provides a precompiled package for every release. 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.1.3 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 clean test

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

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 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
iex> 10 - 5
iex> 10 / 2

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

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

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 this later. Let's move forward and see what 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>>  # bitstring

Elixir by default imports many functions to work on these types:

iex> size { 1, 2, 3 }

iex> length [ 1, 2, 3 ]

Elixir also supports UTF-8 encoded strings:

iex> "hellö"

Strings support interpolation, too:

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

At the end of the day, strings are nothing more than a bunch of bytes packed together. We can verify this using the is_binary function:

iex> is_binary("hello")
iex> byte_size("hello")

And a binary is nothing more than a bunch of bits packed together:

iex> is_bitstring("hello")
iex> bit_size("hello")

Elixir allows you to create "raw" binaries too. Let's create a binary with three null bytes:

iex> is_binary <<0, 0, 0>>

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

iex> is_binary('hello')
iex> is_list('hello')

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

iex> true
iex> is_boolean false

Booleans are represented internally as atoms:

iex> is_atom(true)

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

# function
iex> x = fn(a, b) -> a + b end
iex> x.(1, 2)

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]
iex> [1,2,3] -- [2]

String concatenation is done via <>:

iex> "foo" <> "bar"

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

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

Providing a non-boolean will raise an exception:

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

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

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

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

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

Besides these 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
iex> false || 11

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

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

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

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

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

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

iex> 1 == 1.0
iex> 1 === 1.0

In Elixir, we can compare two different data types:

iex> 1 < :atom

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 < bitstring

You don't actually 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.