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)
end

Elixir

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
2

Wait 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: 2

Elixir

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

Pattern 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 // 2

Elixir

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)
end

This 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

👍👍👍

Made with Slides.com