Elixir as a first functional language
ALCHEMISTS PH MEETUP 03
Functional
programming is beautiful
(defun fib (n &optional (a 0) (b 1))
(if (= n 0)
a
(fib (- n 1) b (+ a b))))Lisp
(defn fib
[n]
(loop [a 0 b 1 i n]
(if (zero? i)
a
(recur b (+ a b) (dec i)))))Clojure
Uhm...
It's an acquired
taste!
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)Haskell
-module(fib).
-export([fib/1]).
fib(1) -> 1;
fib(2) -> 1;
fib(N) -> fib(N - 2) + fib(N - 1).Erlang
defmodule Fibonacci do
def fib(0), do: 0
def fib(1), do: 1
def fib(n), do: fib(n-1) + fib(n-2)
endElixir
That's more readable!
That's more readable?
"Senior" engineer at MashupGarage
Python, JavaScript and Golang
Learning Ruby and Elixir
Mark Steve Samson
2004
2005
2010
2014
Languages timeline
JavaScript (13 years)
PHP (5 years)
Python (6 years)
Golang (2 years)
2016
Why functional programming?
- Pure functions
- No side-effects
- Immutability

function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1
case 'DECREMENT':
return state - 1
default:
return state
}
}

const counter = buildReducer({
'INCREMENT' (state, action) {
return state + 1
},
'DECREMENT' (state, action) {
return state - 1
}
}, 0)
Easy to reason
Math!
First-class functions
make_greeter = fn greeting ->
greeter = fn name ->
greeting <> " " <> name
end
greeter
end
hello = make_greeter.("Hello,")
hello.("World") # "Hello, World"Elixir
Note the dot!
function makeGreeter (greeting) {
var greeter = function (name) {
return greeting + ' ' + name;
}
return greeter;
}
var hello = makeGreeter('Hello,');
hello('World'); // "Hello, World"JavaScript
def make_greeter(greeting):
greeter = lambda name: greeting + \
' ' + name
return greeter
hello = make_greeter('Hello,')
hello('World') # 'Hello, World'Python
Immutability
Elixir
iex> x = 1
1
iex> x = 2
2Wait a minute...
Elixir
iex> x = 1
1
iex> y = x
1
iex> x = 2
2
iex> inspect {x, y}
"{2, 1}"Elixir
iex> x = 1
1
iex> ^x = 2
** (MatchError) no match of right hand
side value: 2Elixir
iex> 1 = x
1
iex> 2 = x
** (MatchError) no match of right hand
side value: 1Pattern matching
Elixir
iex> {a, b, c} = {:hello, "world", 42}
{:hello, "world", 42}
iex> {a, b, c} = {:hello, "world"}
** (MatchError) no match of right hand
side value: {:hello, "world"}Python
>>> x, y = 1, 2
>>> x, y
(1, 2)JavaScript (ES2015)
var [x, y] = [1, 2];
x // 1
y // 2
var {a, b} = {a: 1, b: 2};
a // 1
b // 2Elixir
iex> case {1, 2, 3} do
...> {4, 5, 6} ->
...> "This clause won't match"
...> {1, x, 3} ->
...> "This clause will match and bind x to 2 in this clause"
...> _ ->
...> "This clause would match any value"
...> end
"This clause will match and bind x to 2 in this clause"JavaScript
switch (x) {
case 1: return "one";
case 2: return "two";
case 3: return "three";
default: return "?";
}Elixir
iex> cond do
...> 2 + 2 == 5 ->
...> "This will not be true"
...> 2 * 2 == 3 ->
...> "Nor this"
...> 1 + 1 == 2 ->
...> "But this will"
...> end
"But this will"JavaScript
switch (true) {
case 2 + 2 === 5:
return "This will not be true"
case 2 * 2 === 3:
return "Nor this"
case 1 + 1 === 2:
return "But this will"
}Elixir
iex> [head | tail] = [1, 2, 3]
[1, 2, 3]
iex> head
1
iex> tail
[2, 3]
Python
>>> a = [1, 2, 3]
>>> head = a[0]
>>> tail = a[1:]
>>> head
1
>>> tail
[2, 3]JavaScript (ES2015)
var [head, ...tail] = [1, 2, 3]
head // 1
tail // [2, 3]Elixir
defmodule Fibonacci do
def fib(0), do: 0
def fib(1), do: 1
def fib(n), do: fib(n-1) + fib(n-2)
endThis is MATH
A function relates each element of a set with exactly one element of another set (possibly the same set).
mathisfun.com
Recursion
Elixir
defmodule Math do
def sum_list([head | tail], accumulator) do
sum_list(tail, head + accumulator)
end
def sum_list([], accumulator) do
accumulator
end
end
IO.puts Math.sum_list([1, 2, 3], 0) #=> 6
Functional programming is scary
Functional programming is scary
because it's unfamiliar
👍👍👍

Elixir as a first functional language
By Mark Steve Samson
Elixir as a first functional language
- 629