Elixir is a functional meta-programming aware language built on top of the Erlang VM. It is a dynamic language with flexible syntax with macros support that leverages Erlang's abilities to build concurrent, distributed, fault-tolerant applications with hot code upgrades.
Elixir also provides first-class support to pattern matching, polymorphism via protocols (similar to Clojure's), aliases and associative data structures (usually known as dicts or hashes in other programming languages).
Finally, Elixir and Erlang share the same bytecode and data types. This means you can invoke Erlang code from Elixir (and vice-versa) without any conversion or performance hit. This allows a developer to mix the expressiveness of Elixir with the robustness and performance of Erlang.
To install Elixir or learn more about it, check our getting started guide. We also have online documentation available and a Crash Course for Erlang developers.
Highlights
Everything is an expression
defmodule Hello do
IO.puts "Defining the function world"
def world do
IO.puts "Hello World"
end
IO.puts "Function world defined"
end
Hello.world
Running the program above will print:
Defining the function world Function world defined Hello World
This allows a module to be defined in terms of many expressions, programmable by the developer, being the basic foundation for meta-programming. This is similar to what Joe Armstrong (creator of Erlang) proposes with his erl2 project.
Meta-programming and DSLs
With expressions and meta-programming, Elixir developers can easily create Domain Specific Languages:
defmodule MathTest do
use ExUnit.Case
test "can add two numbers" do
assert 1 + 1 == 2
end
end
DSLs allow a developer to write abstractions for specific domains, often getting rid of boilerplate code.
Polymorphism via protocols
Protocols allow developers to provide type-specific functionality at chosen extension points. For example, the Enum module in Elixir is commonly used to iterate collections:
Enum.map([1,2,3], fn(x) -> x * 2 end) #=> [2,4,6]
Since the Enum module is built on top of protocols, it is not only limited to the data types that ship with Elixir. A developer can use his own collections with Enum as long as it implements the Enum.Iterator protocol. For example, a developer can use all the convenience of the Enum module to easily manipulate a file, line by line:
{ :ok, file } = File.iterator("README.md")
lines = Enum.map(file, fn(line) -> Regex.replace(%r/"/, line, "'") end)
File.write("README.md", lines)
Documentation as first-class citizen
Documentation is supported at language level, in the form of docstrings. Markdown is Elixir's defacto markup language of choice for use in docstrings:
defmodule MyModule do
@moduledoc """
Documentation for my module. With **formatting**.
"""
@doc "Hello"
def world do
"World"
end
end
Different tools can easily access the documentation. For instance, IEx (Elixir's interactive shell) can show the documentation for any module or function with the help of the function h:
iex> h MyModule
# MyModule
Documentation for my module. With **formatting**.
There is also a documentation generator for Elixir called ExDoc that can produce a static site using docstrings extracted from the source code.
Pattern matching
Pattern matching allows developers to easily destructure data and access its contents:
{ User, name, age } = User.get("John Doe")
When mixed with guards, it allows us to easily express our problem:
def serve_drinks({ User, name, age }) when age < 21 do
raise "No way #{name}!"
end
def serve_drinks({ User, name, age }) do
# Code that serves drinks!
end
serve_drinks User.get("John")
#=> Raises "No way John!" if John is under 21
Erlang all the way down
After all, Elixir is still Erlang. An Elixir programmer can invoke any Erlang function with no runtime cost:
:application.start(:crypto)
:crypto.md5("Using crypto from Erlang OTP")
#=> <<192,223,75,115,...>>
Since Elixir compiles to the same bytecode, it is fully OTP compliant and works seamlessly with all the battle-tested techniques Erlang/OTP is famous for. Erlang type specifications, behaviors and module attributes are all supported. It is easy to add Elixir to your existing Erlang programs too (including rebar support)!
To install Elixir or learn more about it, check our getting started guide. We also have online documentation available and a Crash Course for Erlang developers.