Three cool things about Elixir
Here we scratch the surface of Elixir programming language from three different places! Unfortunately we are not going to do a deep plunge, but if you would like to star as a guest writer on Talented blog and share your deeper knowledge on the (tech)topic of your choice, tell us at hello@talented.fi.
Now let’s get started with those three cool things! If this sparkles your interest for more information, you can find few links at the bottom of this blog post.
Pipe-operator
In Elixir, you can nest function calls in two ways:
Traditional Way
Split string into an array (traditional way)
iex> String.split("Secret society of experienced programmers")
["Secret", "society", "of", "experienced", "programmers"]
Uppercase the string and then split it into an array:
iex> String.split(String.upcase("Secret society of experienced programmers"))
["SECRET", "SOCIETY", "OF", "EXPERIENCED", "PROGRAMMERS"]
Using Pipe-Operator
The pipe-operator is quite similar to Unix pipe-operator. You pass the expression to the next expression. Here is how it looks with pipe-operator:
Split string into an array with pipe-operator
iex> "Secret society of experienced programmers" |> String.split
["Secret", "society", "of", "experienced", "programmers"]
Uppercase a string and split it into an array with pipe-operator
iex> "Secret society of experienced programmers" |> String.upcase |> String.split
["Secret", "society", "of", "experienced", "programmers"]
When it really shines
When writing web applications, controller actions become more readable with pipe-operators:
def new(conn, %{"token" => token}) do
user = Resource.find_user_by_token(token)
conn|> assign(:token, token)
|> assign(:email, Map.get(user, :email))
|> render(“new.html”)
end
Pattern Matching
There are many ways to do pattern matching, but using pattern matching with a map of arguments for a function is really cool. With pattern matching, it is guaranteed that you have the parameters you are expecting. It means fewer if-clauses.
def invite(%{"email" => email, "token" => token}) do
“Welcome #{email}! Your token is #{token}”
end
def invite(%{"email" => email) do
“Welcome #{email}!”
end
Some other ways to do pattern matching:
case my_complex_function() do
{:ok, str } -> str
{:error, _} -> nil
end
Fetching value from a Map
iex> args = %{name: "Bill", email: "bill@localhost"}
iex> %{:name => name} = args
iex> name
"Bill"
Asynchronous Function Calls
Elixir is built on top of Erlang VM (BEAM) so all concurrent operations are Elixir’s bread and butter. Erlang was originally designed for telephone call routing applications back in the 80’s and 90’s by Ericsson.
Erlang applications are set of processes and those processes are very lightweight to create and destroy. They share no resources with other processes and they either do their purpose or fail completely. The philosophy with error handling is pretty simple: when an error occurs, just kill the process.
Elixir follows the same philosophy. Small, independent processes doing their given task and when finished, they return the value to parent process and cease to exist.
Learn more
- Elixir School
- The Phoenix Framework, most popular web framework for Elixir
- Getting started with Phoenix Framework