Introduction to Elixir
What is Elixir?
Elixir is a dynamic, functional programming language designed for building scalable and maintainable applications. It runs on the Erlang VM (BEAM), known for creating low-latency, distributed, and fault-tolerant systems.
Key Features
- Functional: Immutable data structures, first-class functions, pattern matching
- Concurrent: Lightweight processes (not OS threads) - spawn millions easily
- Fault-tolerant: "Let it crash" philosophy with supervisor trees
- Scalable: Distributed by design, runs on multiple nodes
- Productive: Modern syntax, powerful metaprogramming, excellent tooling
- Interactive: REPL (IEx) for rapid development and debugging
History
- Created by José Valim in 2011
- Built on Erlang VM (created in 1986 by Ericsson)
- Designed to address productivity while keeping Erlang's strengths
- Used by Discord, Pinterest, Bleacher Report, Financial Times, and more
Installation
Using asdf (Recommended)
asdf allows you to manage multiple runtime versions.
# Install asdf (visit asdf-vm.com for OS-specific instructions)
# Add Erlang and Elixir plugins
asdf plugin add erlang
asdf plugin add elixir
# Install latest versions
asdf install erlang latest
asdf install elixir latest
# Set global versions
asdf global erlang <version>
asdf global elixir <version>
macOS
# Using Homebrew
brew install elixir
Ubuntu/Debian
# Add Erlang Solutions repo
wget https://packages.erlang-solutions.com/erlang-solutions_2.0_all.deb
sudo dpkg -i erlang-solutions_2.0_all.deb
# Install
sudo apt-get update
sudo apt-get install elixir
Windows
Download installer from elixir-lang.org
Verify Installation
elixir --version
You should see output like:
Erlang/OTP 26 [erts-14.2.1] [...]
Elixir 1.16.0 (compiled with Erlang/OTP 26)
Your First Elixir Program
Option 1: Script File
Create a file hello.exs:
IO.puts("Hello, World!")
Run it:
elixir hello.exs
Output:
Hello, World!
Option 2: Interactive Shell (IEx)
IEx is Elixir's interactive shell - think Python's REPL or Node's console.
iex
Try some commands:
iex> IO.puts("Hello, World!")
Hello, World!
:ok
iex> 1 + 2
3
iex> "hello" <> " " <> "world"
"hello world"
iex> String.upcase("elixir")
"ELIXIR"
IEx Tips
# Get help
iex> h String.upcase
# Autocomplete - press Tab
iex> String.up<TAB>
# Multiline input - use \
iex> 1 + \
...> 2
3
# Get type information
iex> i "hello"
# Shows detailed info about the string
# Previous result with `v`
iex> 1 + 2
3
iex> v()
3
iex> v() * 2
6
# Exit IEx
iex> exit # or Ctrl+C twice
Basic Syntax Overview
Comments
# This is a single-line comment
# There are no multi-line comments in Elixir
# Just use multiple single-line comments
Basic Types
# Integer
42
# Float
3.14
# Boolean
true
false
# Atom (like Ruby symbols or enum values)
:ok
:error
:hello
# String (UTF-8)
"Hello, World!"
# List
[1, 2, 3]
# Tuple
{:ok, "result"}
# Map
%{name: "Alice", age: 30}
Basic Operations
# Arithmetic
iex> 1 + 2
3
iex> 10 - 5
5
iex> 3 * 4
12
iex> 10 / 2
5.0 # Always returns float
iex> div(10, 3) # Integer division
3
iex> rem(10, 3) # Remainder
1
# String concatenation
iex> "Hello" <> " " <> "World"
"Hello World"
# String interpolation
iex> name = "Alice"
"Alice"
iex> "Hello, #{name}!"
"Hello, Alice!"
# Boolean operators
iex> true and false
false
iex> true or false
true
iex> not true
false
# Comparison
iex> 1 == 1
true
iex> 1 != 2
true
iex> 1 < 2
true
iex> 1 >= 1
true
# Strict equality (checks type too)
iex> 1 == 1.0 # true (values are equal)
true
iex> 1 === 1.0 # false (different types)
false
Running Elixir Code
Three Ways to Execute
| Method | Use Case | Command |
|---|---|---|
| Script | Run a .exs file | elixir script.exs |
| IEx | Interactive exploration | iex |
| Mix Project | Full application | mix run |
Script Files
Elixir uses two file extensions:
.exs- Elixir Script (interpreted, not compiled).ex- Elixir source (compiled into .beam files)
For learning, use .exs scripts:
# calculate.exs
defmodule Calculator do
def add(a, b), do: a + b
def multiply(a, b), do: a * b
end
IO.puts("3 + 4 = #{Calculator.add(3, 4)}")
IO.puts("3 * 4 = #{Calculator.multiply(3, 4)}")
Run:
elixir calculate.exs
Output:
3 + 4 = 7
3 * 4 = 12
Loading Code in IEx
# Load a file into IEx
iex> c "calculate.exs"
[Calculator]
# Now you can use the module
iex> Calculator.add(5, 3)
8
Your First Module
# greeter.exs
defmodule Greeter do
def hello(name) do
"Hello, #{name}!"
end
def goodbye(name) do
"Goodbye, #{name}!"
end
end
# Call the functions
IO.puts Greeter.hello("World")
IO.puts Greeter.goodbye("World")
Run:
elixir greeter.exs
Output:
Hello, World!
Goodbye, World!
Elixir Philosophy
1. Let It Crash
Unlike traditional error handling, Elixir embraces failures:
# Instead of defensive programming everywhere
# Let processes crash and supervisors restart them
# This leads to cleaner, more maintainable code
2. Immutability
All data is immutable - no variables change:
list = [1, 2, 3]
new_list = [0 | list] # Creates new list: [0, 1, 2, 3]
# Original list unchanged: [1, 2, 3]
3. Pattern Matching
Assignment is actually pattern matching:
{:ok, result} = {:ok, 42}
# result is now 42
{:ok, result} = {:error, "failed"}
# ** (MatchError) - pattern doesn't match!
4. Transformation Pipeline
Data flows through transformations:
"hello world"
|> String.upcase()
|> String.split()
# => ["HELLO", "WORLD"]
Common Gotchas for Beginners
1. Variables Don't Vary (Much)
x = 1
x = 2 # This is actually rebinding, not mutation
# The original value 1 still exists elsewhere
2. Division Returns Float
10 / 2 # => 5.0 (not 5)
div(10, 2) # => 5 (integer division)
3. Atoms Are Not Strings
:hello != "hello" # Different types
4. Lists Are Linked Lists
# Fast operations
[0 | list] # Prepend: O(1)
# Slow operations
list ++ [4] # Append: O(n)
length(list) # Length: O(n)
# Use Enum.count/1 for any enumerable
5. Parentheses Are Optional (But Use Them)
# Both work
String.upcase("hello")
String.upcase "hello"
# But be consistent (use parentheses for clarity)
Next Steps
Now that you have Elixir installed and understand the basics, you're ready to dive into:
- Variables and types - Deep dive into Elixir's type system
- Pattern matching - The secret sauce of Elixir
- Functions - First-class functions and function clauses
- Collections - Lists, tuples, maps, and how to work with them
Continue to 02-basics.md to learn about variables, types, and pattern matching in depth.
Exercise
Try these in IEx to get comfortable:
- Calculate the area of a circle with radius 5 (π * r²)
- Create a string with your name and use
String.length/1to count characters - Create a list
[1, 2, 3]and prepend 0 to it - Use string interpolation to create "Hello, #{your_name}!"
- Try using the pipe operator:
"HELLO" |> String.downcase() |> String.reverse()
# Solutions
iex> 3.14159 * 5 * 5
78.53975
iex> name = "Alice"
"Alice"
iex> String.length(name)
5
iex> [0 | [1, 2, 3]]
[0, 1, 2, 3]
iex> "Hello, #{name}!"
"Hello, Alice!"
iex> "HELLO" |> String.downcase() |> String.reverse()
"olleh"