My First Week With Elixir As A Rubyist
Tags: elixir, functional, oop, ruby
Published: 2019-06-11 21:22:42

I recently started learning Elixir for an upcoming project. As part of my usual prep work, I have studied the [language documentation](https://elixir-lang.org/), walked through the [Koans](https://github.com/elixirkoans/elixir-koans), and practiced some katas on [Exercism.io](https://exercism.io).

The end result is a few changes to how I approach problem solving, that I want to share with you. 

Before we jump in, some things you might find confusing are:

1) Function signatures include the number of parameters that they take, referred to as arity. A function signature `any?(collection, fn)` would be referred to as `any?/2`. 

2) Unused parameters are named but are prefixed with an underscore.

3) `iex` is the name of the REPL in Elixir.

# Pattern matching and Decomposition

Pattern matching as a first class idea is new to me. Usually I would avoid case statements and destructuring, and favor polymorphism, but I have begun to play with some of the interesting cases that are possible.


Let's look at an example. Here I match the variable `a` to a pattern of a string literal.

``` 
iex> a = "Some String" # Binds string to a
"Some String"
iex> "Some String" = a # Matches a to the pattern
"Some String"
```

Pattern matching throws an error when there is not a match.

```
iex> "Not a Match" = a # Throws an error
** (MatchError) no match of right hand side value: "Some String"
```

It is possible to destructure lists using pattern matching. Here you can see how to separate the first element of a list from the rest of it.

```
iex> [head | tail] = [1, 2, 3, 4, 5]
iex> head
1
iex> tail
[2, 3, 4, 5]
```

You can also destructure more complex data types. For instance, grabbing a key out of a map:

```
iex> user = %{id: 1, login: %{user_name: 'bob114', password: 'Apple12Sauce!'}}
iex> %{id: id} = user
iex> id
1
iex> %{login: %{user_name: user_name}} = user
iex> user_name
bob114
```

# Recursion First
I had to adapt my style to embrace recursion. That last time that I wrote so much recursive code was in a computer science course. This is a drastic style change but would be best demonstrated through an example of navigating collections.

Let's create a function to determine if any element is contained in a collection, and name the function `any?/2`.

I start by asking, "What is the base case for `any?/2`?". 

It would be when the list parameter is empty. Using pattern matching we can define a function header that will match the scenario where the first element passed is an empty list, and return `false`.


``` elixir
defmodule Example do
  def any?([], _a), do: false # Matches when the first param is an empty list
end
```

Next I think ask, "What could be the recursive case?"

When the list is not empty, I try to divide the problem into smaller parts, allowing me to hit the base cases. There are two possibilities, 1) the first element is equal to the variable, 2) it isn't and we need to keep looking. If we implement scenario one, then we have the `head` equal to `a`, so we return true.

``` elixir
defmodule Example do
  def any?([], _a), do: false
  def any?([head | _tail], a) do
    if head == a do
      true
    end
  end
end
```

In the last scenario we deal with recursing the rest of the list.

``` elixir
defmodule Example do
  def any?([], _a), do: false
  def any?([head | tail], a) do
    if head == a do
      true
    else 
      any?(tail, a) 
    end
  end
end
```

# Maintaining state

In Elixir state is managed inside of processes. Each process emulates state transitions by using recursion. Processes allow their state to be changed or queried by other processes via messages. Rather than show you the low level tooling (`spawn`, `Agent`, or `Task`), the most high-level construct I am aware of is the `GenServer`. 

`GenServer` is a core language construct that wraps all the complexity around a process sending and receiving messages. It is a module that has two types of functions, asynchronous and synchronous. 

Synchronous functions are `call`s, they will reply to the calling process with some data. They do this by returning a tuple like `{:reply, data, state}`. The `:reply` tells the server to respond to the caller, the data is what to send in the reply, and the state is the new state for the process.

``` elixir
defmodule OurServer do
  use GenServer
  
  ...
  
  def call({:message, caller_data}, _from, state) do
    {:reply, caller_data, [caller_data]}
  end
end
```

Asynchronous functions are `cast`s, they do not reply to callers. They return a tuple like `{:noreply, state}`. `:noreply` tells the server not to reply, and `state` is the new state for the process.

``` elixir
defmodule OurServer do
  use GenServer

  def cast({:message, caller_data}, state) do
    {:noreply, caller_data}
  end
end
```

In future articles, I plan to discuss `GenServer`s more deeply, but that's all for now.

# Conclusion

I am venturing out into the wilderness of Functional Languages by trying Elixir for the first time. 

The things I found the most interesting on week one are:
- Pattern matching
- Recursion first
- Emulating state with processes

If you enjoyed this article and want to read more about Elixir, please leave a comment or a like below. Thanks!