Fun Things in Elixir
Tags: elixir, functional, programming
Published: 2016-11-04 14:14:39

---
title: Fun Things in Elixir
published: true
description: A brief, beginner-friendly look at five interesting aspects of the Elixir programming language.
cover_image: 
tags: Elixir, Functional Programming, Programming
---

I've recently been learning [Elixir](http://elixir-lang.org/), a functional programming language that leverages the [Erlang](https://www.erlang.org/) VM. I've found a number of aspects of the language and its documentation to be both interesting and powerful. This post is a brief exploration into some of those elements.

-----

## 1. Documentation syntax for function arity

If you're unfamiliar with arity, [Wikipedia offers a good definition](https://en.wikipedia.org/wiki/Arity). In short, the arity of a function is the number of arguments that are expected or accepted by a function.

Functions are commonly listed in the Elixir docs in the form of `name/arity`. For example, the [count functions in the Enum module](http://elixir-lang.org/docs/stable/elixir/Enum.html#count/1) would be listed as:

```elixir
Enum.count/1
Enum.count/2
```

This indicates that there are two count functions: one which takes one argument, and a second that accepts two.

If a function takes no arguments, for example the [new function in the Map module](http://elixir-lang.org/docs/stable/elixir/Map.html#new/0), it would be listed as:

```elixir
Map.new/0
```

## 2. The Pipe Operator ( |> )
Elixir offers a beautiful shorthand for function chaining. Somewhat similar to promises in JavaScript, the pipe operator in Elixir automatically passes the value of the expression evaluation to the next function. If the function call on the right has an arity > 1, those arguments can still be provided, while the first argument is not necessary to provide explicitly, as it has been provided by the pipe operator.

Here are two identical operations — the first without the pipe operator, and the second refactored with use of the pipe operator.

```elixir
# Without |>
my_string = "hello there, how are you?"
split_string = String.split(my_string, ",")
=> ["hello there", " how are you?"]

# With |>
split_string = "hello there, how are you?" |> String.split(",")
=> ["hello there", " how are you?"]
```

This example is very basic and chains only once. Even at this level, it's saved us a line of code without sacrificing readability. When chaining at several levels, the pipe operator really starts to shine. Look at this example from the [official docs](http://elixir-lang.org/getting-started/enumerables-and-streams.html#the-pipe-operator):

```elixir
# Without |>
Enum.sum(Enum.filter(Enum.map(1..100_000, &(&1 * 3)), odd?))
=> 7500000000

# With |>
1..100_000
  |> Enum.map(&(&1 * 3)) 
  |> Enum.filter(odd?) 
  |> Enum.sum
=> 7500000000
```

## 3. Function definitions with clauses

Elixir allows you to create the same function with different clauses, utilizing the clause in its definition to determine which version of the function gets called.

```elixir
defmodule SomeModule do

  def foo(arg \\ nil) when is_nil(arg) do
    IO.puts "No argument provided."
  end

  def foo(arg) do
    IO.puts "You provided the argument: #{arg}."
  end

end
```

In the above example, I've defined function `foo/1` and set a default value for the arg of `nil`. If that function is called without an argument, a message is printed indicating such:

```elixir
> SomeModule.foo
=> No argument provided.
```

Otherwise, the value of the arg is interpolated and printed:

```elixir
> SomeModule.foo(12)
=> You provided the argument: 12.
```

## 4. In-code documentation and testing

Elixir allows documentation for public functions to be created by the developer within the code itself.

```elixir
defmodule MainProgram.SomeModule do
  
  @doc """
  Takes an integer argument and returns the square of that value.
  """
  def squared(num) when is_integer(num) do
    num * num
  end

end
```

When running this module in [IEx](http://elixir-lang.org/docs/stable/iex/IEx.html), Elixir's interactive shell, we'd have access to this documentation the same as any other, accessible with the `h` (help) command:

```elixir
iex> h MainProgram.SomeModule.squared

                        def squared(num)

Takes an integer argument and returns the square of that value.
```

Even better, unit tests can be created within this same documentation:

```elixir
defmodule MainProgram.SomeModule do
  
  @doc """
  Takes an integer argument and returns the square of that value.
  
  ## Examples
      iex> MainProgram.SomeModule.squared(2)
      4
      iex> MainProgram.SomeModule.squared(-4)
      16
  """
  def squared(num) when is_integer(num) do
    num * num
  end

end
```

When running `mix test`, the two tests listed under `## Examples` will be run with all other tests in the test suite. To ensure this happens, the tests in the documentation need to be prefaced by `iex>` and be indented by four spaces, and in our `SomeModuleTest` file we need to list `doctest`:

```elixir
defmodule MainProgram.SomeModuleTest do
  use ExUnit.Case, async: true
  doctest MainProgram.SomeModule
end
```

That's it. We now have tests that will run with `mix test` AND provide helpful examples as part of our documentation:

```elixir
iex> h MainProgram.SomeModule.squared

                         def squared(num)

Takes an integer argument and returns the square of that value.

Examples
| iex> MainProgram.SomeModule.squared(2)
| 4
| iex> MainProgram.SomeModule.squared(-4)
| 16
iex>
```

## 5. Pattern Matching

Last but certainly not least is pattern matching, an extremely powerful aspect of Elixir. This topic could be a blog post of its own (and, in fact, does already exist as an [excellent blog post](https://quickleft.com/blog/pattern-matching-elixir/)), so this section will be a very brief introduction.

In Elixir, the `=` operator is officially the ‘match operator.' This is because it's actually performing a comparison of its left and right sides. Variable assignment still works as expected:

```elixir
iex> x = 1
=> 1
```

But flipping sides can show us how comparisons are taking place:

```elixir
iex> x
=> 1
iex> 1 = x
=> 1
iex> 2 = x
=> ** (MatchError) no match of right hand side value: 1
```

It's actually comparing the left and right sides to confirm a match. Note that, for variable assignment to occur, the variable must be on the left side of the match operator.

Pattern matching is more commonly used with [tuples](http://elixir-lang.org/getting-started/basic-types.html#tuples):

```elixir
iex> {a, b, c} = {1, :hi, "3"}
{1, :hi, "3"}
iex> a
1
iex> b
:hi
iex> c
"3"
```

On the surface, this looks very similar to assigning multiple variables in Ruby:

```ruby
2.3.1 :001 > a, b, c = 1, :hi, "3"
 => [1, :hi, "3"]
2.3.1 :002 > a
 => 1
2.3.1 :003 > b
 => :hi
2.3.1 :004 > c
 => "3"
```

But keep in mind that matching is still taking place, allowing us to only assign variables when certain conditions are met:

```elixir
iex> {:ok, result} = {:ok, 13}
{:ok, 13}
iex> result
13

iex> {:ok, result} = {:error, :oops}
** (MatchError) no match of right hand side value: {:error, :oops}
```

As mentioned, pattern matching is worth diving into in more depth. In addition to the basic use case explored above, it can also be used with data structures and functions. If you're interested, check out the [official site](http://elixir-lang.org/getting-started/pattern-matching.html) (where the final code example came from) or the aforementioned [blog](https://quickleft.com/blog/pattern-matching-elixir/).