A Quick Dive in Elixir
Tags: elixir, basics
Published: 2019-09-25 14:10:11

---
title: A Quick Dive in Elixir
published: true
description: I go through my standard learning process for a new language.
tags: elixir, basics
cover_image: https://upload.wikimedia.org/wikipedia/commons/0/08/Capstan2_%28PSF%29.jpg
---


# What is elixir?

Yet another programming language.  There are some unique characteristics of elixir that I have not experienced with other languages.  First, the way I approach learning a new language might be of interest.  What I do is start a repo for the language or framework, in this case `elixir-kiss` (keep it simple stupid).  

{% github kyleparisi/elixir-kiss %}

From there I start exploring basic ideas that I'm curious about and make branches off the original test bed.

# What can you do with elixir?

The main thing you'll find elixir being used for is some kind of distributed system.  It's a fun idea to think of a cluster of computers as a single application.  To get an application "networked" together, you can do this in a few lines.  Here is one example using a library that clusters 2 nodes.

```elixir
defmodule MyApp.App do
  use Application

  def start(_type, _args) do
    topologies = [
      example: [
        strategy: Cluster.Strategy.Epmd,
        config: [hosts: [:"a@127.0.0.1", :"b@127.0.0.1"]],
      ]
    ]
    children = [
      {Cluster.Supervisor, [topologies, [name: MyApp.ClusterSupervisor]]},
      # ..other children..
    ]
    Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
  end
end
```

There are a couple ways you could cluster your applications.  The above example uses a builtin strategy called [Erlang Port Mapper Daemon](http://erlang.org/doc/man/epmd.html).  Things like DNS, Multicast UDP gossip, or other API based methods can be used.

# What is unique about elixir?

There are a number of unique attributes of elixir.  Elixir's control flow is heavily based on pattern matching.  This means you define functions based on the data structure being passed in.  That looks something like:

```elixir
  post "/login" do
    {:ok, body, conn} = read_body(conn)
    case Poison.decode(body) do
      {:ok, %{"email" => "", "password" => ""}} ->
        send_resp(conn, 400, Poison.encode!(%{errors: %{email: "Please provide an email.", password: "Please provide a password"}}))
      {:ok, %{"email" => email, "password" => password}} ->
        send_resp(conn, 200, "")
      {:error, :invalid, 0} ->
        Logger.info("No body provided for /login")
        send_resp(conn, 400, Poison.encode!(%{errors: %{email: "Please provide an email.", password: "Please provide a password"}}))
      {:ok, %{"email" => email}} ->
        Logger.info("No password provided for /login")
        send_resp(conn, 400, Poison.encode!(%{errors: %{password: "Please provide a password"}, email: email}))
      {:ok, %{"password" => _}} ->
        Logger.info("No email provided for /login")
        send_resp(conn, 400, Poison.encode!(%{errors: %{email: "Please provide an email."}}))
    end
  end
```

In elixir there are no return or break statements.  The last line in a function is the return statement.  This one really caught me off guard.  Return statements are definitely designed for procedural mentality.  Not having returns really emphasizes the pattern matching functionality.

Documentation is a first class citizen.  I've never seen this before.

```elixir
defmodule Math do
  @moduledoc """
  Provides math-related functions.

  ## Examples

      iex> Math.sum(1, 2)
      3

  """

  @doc """
  Calculates the sum of two numbers.
  """
  def sum(a, b), do: a + b
end
```

If you configure your tests to use doctests, it will actually assert against the `iex>` statements.  Very cool.

Running elixir can be pretty complex due to it's distributed nature.  But elixir is using erlang under the hood which happens to come with some handy *GUI* tools built in.  You can see some of that [here](https://elixir-lang.org/getting-started/debugging.html).

 > "Let it crash".  Elixir – and Erlang – encourage you to code the happy path.  Runtime errors should be allowed to crash the process. [^1]

Lastly, elixir has a `Read Eval Print Loop` (REPL) runtime ability that makes it easy to test thoughts and explore the running application.

# What I don't like

Even though elixir has reasonable types (tuples, maps, lists, etc.), doing type conversion I found to be confusing.  If I wanted to cast something from a map into a user defined struct, it did not go smoothly.  

I was not very pleased with the database driver.  The most recommended interface is an abstracted library called [Ecto](https://hexdocs.pm/ecto/Ecto.html).  To use this interface you have to define repos, schemas, changesets or queries.  The queries look like some kind of `Domain Specific Language` (DSL) and changsets is a foreign concept to me.  It's surprising that connections, prepared statements, and queries is not the suggested driver.

Some library documentation, although heavily documented, doesn't seem very helpful at times.

# Final thoughts

There isn't a language that is the silver bullet for all problems.  Elixir is no different.  It's still a young language, being originally created in only 2011, it's foundation is based on erlang which is much older.  I may look back at it when I have a need for distribution or clustering.

Some interesting links:
[^1]: [https://10consulting.com/presentations/building-cqrs-es-web-applications-in-elixir/#34](https://10consulting.com/presentations/building-cqrs-es-web-applications-in-elixir/#34)
- [https://elixirschool.com/en/](https://elixirschool.com/en/)
- [https://engineering.dollarshaveclub.com/elixir-otp-applications-on-kubernetes-9944636b8609](https://engineering.dollarshaveclub.com/elixir-otp-applications-on-kubernetes-9944636b8609)
- [http://tech.nextroll.com/blog/dev/2018/01/08/quaff-that-potion-saving-millions-with-elixir-and-erlang.html](http://tech.nextroll.com/blog/dev/2018/01/08/quaff-that-potion-saving-millions-with-elixir-and-erlang.html)
- [https://tonyc.github.io/posts/managing-external-commands-in-elixir-with-ports/](https://tonyc.github.io/posts/managing-external-commands-in-elixir-with-ports/)
- [https://blog.carbonfive.com/2018/01/30/comparing-dynamic-supervision-strategies-in-elixir-1-5-and-1-6/](https://blog.carbonfive.com/2018/01/30/comparing-dynamic-supervision-strategies-in-elixir-1-5-and-1-6/)
- [https://github.com/plausible-insights/plausible](https://github.com/plausible-insights/plausible)
- [Youtube - Hot code swapping](https://www.youtube.com/watch?v=CZWMc2cXUAw)