SlideShare a Scribd company logo
ELIXIR
the not-so-hidden path to Erlang
A Coruña, February 1st, 2018
Laura M. Castro
Universidade da Coruña 1
2
3
Born in 1986, released ’98
Concurrency-oriented
◦ Lightweight, isolated
processes,
message-passing
communication
Multiplatform VM
Transparent distribution
OTP behaviours
Hot code swap
3
Born in 1986, released ’98
Concurrency-oriented
◦ Lightweight, isolated
processes,
message-passing
communication
Multiplatform VM
Transparent distribution
OTP behaviours
Hot code swap
3
Born in 2011
Runs on the Erlang VM
Can invoke Erlang code
Born in 1986, released ’98
Concurrency-oriented
◦ Lightweight, isolated
processes,
message-passing
communication
Multiplatform VM
Transparent distribution
OTP behaviours
Hot code swap
3
Dynamic typing
Single assignment
Eager evaluation
4
Dynamic typing
Variable rebinding
Lazy collections
Strings are not lists
Pipeline operator
Namespaces
Polymorphism via
protocols
Dynamic typing
Single assignment
Eager evaluation
4
Dynamic typing
Variable rebinding
Lazy collections
Strings are not lists
Pipeline operator
Namespaces
Polymorphism via
protocols
Dynamic typing
Single assignment
Eager evaluation
4
5
HELLO, WORLD!
1 defmodule World do
2
3 def hello(who) do
4 IO.puts "Hello, #{inspect who}!"
5 end
6
7 end
1 -module(world).
2
3 -export([hello/1]).
4
5 hello(Who) ->
6 io:format("Hello, ~p!~n", [Who]).
6
HELLO, WORLD!
1 defmodule World do
2
3 def hello(who) do
4 IO.puts "Hello, #{inspect who}!"
5 end
6
7 end
1 -module(world).
2
3 -export([hello/1]).
4
5 hello(Who) ->
6 io:format("Hello, ~p!~n", [Who]).
6
HELLO, WORLD!
1 defmodule World do
2
3 def hello(who) do
4 IO.puts "Hello, #{inspect who}!"
5 end
6
7 end
1 -module(world).
2
3 -export([hello/1]).
4
5 hello(Who) ->
6 io:format("Hello, ~p!~n", [Who]).
6
SIMPLE MODULE
1 defmodule Boolean do
2 @moduledoc """
3 Simple pattern matching
4 """
5
6 @doc """
7 Operator ’not’.
8
9 ## Parameters
10
11 - value: boolean to be negated
12
13 """
14 @spec b_not(boolean) :: boolean
15 def b_not(true), do: false
16 def b_not(false), do: true
17
18 @doc """
19 Operator ’and’.
20
21 ## Parameters
22
23 - value1, value2: booleans to operate
24
25 """
26 @spec b_and(boolean , boolean) ::
boolean
27 def b_and(true, true), do: true
28 def b_and(_, _), do: false
1 %%% @doc Simple pattern matching
2 %%% @end
3 -module(boolean).
4
5 -export([b_not/1, b_and/2]).
6
7 %% @doc Operator ’not’.
8 %% @end
9 -spec b_not(Value :: boolean()) ->
boolean().
10 b_not(true) -> false;
11 b_not(false) -> true.
12
13 %% @doc Operator ’and’.
14 %% @end
15 -spec b_and(Value1 :: boolean(),
16 Value2 :: boolean()) ->
boolean().
17 b_and(true, true) ->
18 true;
19 b_and(Value1, Value2) ->
20 false.
7
SIMPLE MODULE
7
SIMPLE MODULE
7
SIMPLE MODULE
7
UNIT TESTS
1 ExUnit.start
2
3 defmodule BooleanTest do
4 @moduledoc """
5 Simple pattern matching (tests)
6 """
7
8 use ExUnit.Case
9 doctest Boolean
10
11 test "Boolean negation" do
12 assert Boolean.b_not(false)
13 refute Boolean.b_not(true)
14 end
15
16 test "Boolean AND" do
17 assert Boolean.b_and(true, true)
18 refute Boolean.b_and(true, false)
19 refute Boolean.b_and(false, true)
20 refute Boolean.b_and(false, false)
21 end
22
23 end
1 %%% @doc Simple pattern matching (tests)
2 %%% @end
3 -module(boolean_tests).
4
5 -include_lib("eunit/include/eunit.hrl").
6
7 b_not_test() ->
8 ?assert(boolean:b_not(false)),
9 ?assertNot(boolean:b_not(true)).
10
11 b_and_test() ->
12 ?assert(boolean:b_and(true,true)),
13 ?assertNot(boolean:b_and(true,false)),
14 ?assertNot(boolean:b_and(false,true)),
15 ?assertNot(boolean:b_and(false,false)).
8
UNIT TESTS
8
SIMPLE MODULE (II)
1 defmodule Create do
2 @moduledoc """
3 Creating lists
4 """
5
6 def create(n) when n>0 do
7 acc_forward(1, n, [])
8 end
9
10 def reverse_create(n) when n>0 do
11 acc_backwards(n, 1, [])
12 end
13
14 def acc_forward(a, a, l), do: [a|l]
15 def acc_forward(a, b, l), do:
acc_forward(a, b-1, [b|l])
16
17 def acc_backwards(a, a, l), do: [a|l]
18 def acc_backwards(a, b, l), do:
acc_backwards(a, b+1, [b|l])
19
20 end
1 %%% @doc Creating lists
2 %%% @end
3 -module(create).
4
5 -export([create/1, reverse_create/1]).
6
7 create(N) when N>0 ->
8 acc_forward(1, N, []).
9
10 reverse_create(N) when N>0 ->
11 acc_backwards(N, 1, []).
12
13 acc_forward(A, A, L) -> [A | L];
14 acc_forward(A, B, L) ->
15 acc_forward(A, B-1, [B | L]).
16
17 acc_backwards(A, A, L) -> [A | L];
18 acc_backwards(A, B, L) ->
19 acc_backwards(A, B+1, [B | L]).
9
PROPERTY-BASED TESTS
1 defmodule CreateProps do
2 @moduledoc """
3 Creating lists (test properties)
4 """
5
6 use ExUnit.Case
7 use PropCheck
8 doctest Create
9
10 property "List creation" do
11 forall i <- positive_integer() do
12 Create.create(i+1) == Enum.to_list
(1..i+1)
13 end
14 end
15
16 property "Reverse list creation" do
17 forall i <- positive_integer() do
18 Create.reverse_create(i+1) == Enum.
reverse(Enum.to_list(1..i+1))
19 end
20 end
21
22 end
1 %%% @doc Creating lists (test properties)
2 %%% @end
3 -module(create_props).
4
5 -include_lib("proper/include/proper.hrl")
.
6 -compile(export_all).
7
8 prop_create() ->
9 ?FORALL(I, positive_integer(),
10 create:create(I) == lists:seq(1, I)).
11
12 prop_reverse_create() ->
13 ?FORALL(I, positive_integer(),
14 create:reverse_create(I) == lists:
reverse(lists:seq(1, I))).
10
PROPERTY-BASED TESTS
1 defmodule CreateProps do
2 @moduledoc """
3 Creating lists (test properties)
4 """
5
6 use ExUnit.Case
7 use PropCheck
8 doctest Create
9
10 property "List creation" do
11 forall i <- positive_integer() do
12 Create.create(i+1) == Enum.to_list
(1..i+1)
13 end
14 end
15
16 property "Reverse list creation" do
17 forall i <- positive_integer() do
18 Create.reverse_create(i+1) == Enum.
reverse(Enum.to_list(1..i+1))
19 end
20 end
21
22 end
1 %%% @doc Creating lists (test properties)
2 %%% @end
3 -module(create_props).
4
5 -include_lib("proper/include/proper.hrl")
.
6 -compile(export_all).
7
8 prop_create() ->
9 ?FORALL(I, positive_integer(),
10 create:create(I) == lists:seq(1, I)).
11
12 prop_reverse_create() ->
13 ?FORALL(I, positive_integer(),
14 create:reverse_create(I) == lists:
reverse(lists:seq(1, I))).
10
PROPERTY-BASED TESTS
10
PROPERTY-BASED TESTS
10
SIMPLE PROCESS
11
SIMPLE PROCESS
1 defmodule DbProcess do
2 @moduledoc """
3 Database handling using a process
4 """
5
6 def new(), do: spawn(DbProcess , :loop,
[[]])
7
8 def write(key, element , dbref) do
9 send dbref, {:write, key, element}
10 dbref
11 end
12
13 def delete(key, dbref) do
14 send dbref, {:delete, key}
15 dbref
16 end
17
18 def read(key, dbref) do
19 send dbref, {:read, key, self()}
20 receive do
21 {_dbref, :found, element} -> {:ok,
element}
22 {_dbref, :notfound} -> {:
error, :instance}
23 end
24 end
1 %%% @doc Database handling using a
process
2 %%% @end
3 -module(db_process).
4
5 -export([new/0, write/3, delete/2, read
/2, match/2, destroy/1]).
6
7 new() ->
8 spawn(?MODULE, loop, [[]]).
9
10 write(Key, Element , DbRef) ->
11 DbRef ! {write, Key, Element},
12 DbRef.
13
14 delete(Key, DbRef) ->
15 DbRef ! {delete, Key},
16 DbRef.
17
18 read(Key, DbRef) ->
19 DbRef ! {read, Key, self()},
20 receive
21 {DbRef, found, Element} -> {ok,
Element};
22 {DbRef, notfound} -> {error,
instance}
23 end.
11
SIMPLE PROCESS
25 def match(element , dbref) do
26 send dbref, {:match, element , self()}
27 receive do
28 {_dbref, keys} -> keys
29 end
30 end
31
32 def destroy(dbref) do
33 send dbref, :stop
34 :ok
35 end
24 match(Element , DbRef) ->
25 DbRef ! {match, Element , self()},
26 receive
27 {DbRef, Keys} -> Keys
28 end.
29
30 destroy(DbRef) ->
31 DbRef ! stop,
32 ok.
11
SIMPLE PROCESS
36 def loop(db) do
37 receive do
38 {:write, key, element} -> loop([{
key, element} | db])
39 {:delete, key} -> loop(
acc_delete(key, db, []))
40 {:read, key, who} ->
41 case List.keyfind(db, key, 0) do
42 nil -> send who, {
self(), :notfound}
43 {_key, element} -> send who, {
self(), :found, element}
44 end
45 loop(db)
46 {:match, element , who} ->
47 keys = acc_match(element , db, [])
48 send who, {self(), keys}
49 loop(db)
50 :stop ->
51 :ok
52 end
53 end
33 loop(Db) ->
34 receive
35 {write, Key, Element} ->
36 loop([{Key, Element} | Db]);
37 {delete, Key} ->
38 loop(lists:keydelete(Key, 1, Db));
39 {read, Key, Who} ->
40 case lists:keyfind(Key, 1, Db) of
41 false ->
42 Who ! {self(), notfound};
43 {Key, Element} ->
44 Who ! {self(), found, Element}
45 end,
46 loop(Db);
47 {match, Element , Who} ->
48 Keys = acc_match(Element , Db, []),
49 Who ! {self(), Keys},
50 loop(Db);
51 stop ->
52 ok
53 end.
11
SIMPLE OTP PROCESS
1 defmodule DbGenServer do
2 @moduledoc """
3 Database handling using OTP
4 """
5
6 use GenServer
7
8 def new() do
9 GenServer.start_link(__MODULE__ , [],
name: DbGenServer)
10 end
11
12 def write(key, element) do
13 GenServer.cast(DbGenServer , {:write,
key, element})
14 end
15
16 def delete(key) do
17 GenServer.cast(DbGenServer , {:delete,
key})
18 end
19
20 def read(key) do
21 GenServer.call(DbGenServer , {:read,
key})
22 end
1 %% @doc Database handling using OTP
2 %% @end
3 -module(db_gen_server).
4 -behaviour(gen_server).
5
6 -export([new/0, write/2, delete/1, read
/1, match/1, destroy/0]).
7 -export([init/1, handle_call/3,
handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
8
9 -define(SERVER, ?MODULE).
10
11 new() ->
12 gen_server:start_link({local, ?SERVER},
?MODULE, [], []).
13
14 write(Key, Element) ->
15 gen_server:cast(?SERVER, {write, Key,
Element}).
16
17 delete(Key) ->
18 gen_server:cast(?SERVER, {delete, Key})
.
19
20 read(Key) ->
21 gen_server:call(?SERVER, {read, Key}).
12
SIMPLE OTP PROCESS
23 def match(element) do
24 GenServer.call(DbGenServer , {:match,
element})
25 end
26
27 def destroy() do
28 GenServer.stop(DbGenServer)
29 end
30
31 ## GenServer Callbacks
32
33 def init([]) do
34 {:ok, []}
35 end
36
37 def handle_call({:read, key}, _from,
state) do
38 reply = case List.keyfind(state, key,
0) do
39 nil -> {:error, :instance}
40 {_key, element} -> {:ok, element}
41 end
42 {:reply, reply, state}
43 end
44 def handle_call({:match, element},
_from, state) do
45 keys = acc_match(element , state, [])
46 {:reply, keys, state}
47 end
22 match(Element) ->
23 gen_server:call(?SERVER, {match,
Element}).
24
25 destroy() ->
26 gen_server:stop(?SERVER).
27
28 % gen_server callbacks
29
30 init([]) ->
31 {ok, []}.
32
33 handle_call({read, Key}, _From, State) ->
34 Reply = case lists:keyfind(Key, 1,
State) of
35 false ->
36 {error, instance};
37 {Key, Element} ->
38 {ok, Element}
39 end,
40 {reply, Reply, State};
41 handle_call({match, Element}, _From,
State) ->
42 Keys = acc_match(Element , State, []),
43 {reply, Keys, State}.
12
SIMPLE OTP PROCESS
48 def handle_cast({:write, key, element},
state) do
49 {:noreply , [{key, element} | state]}
50 end
51 def handle_cast({:delete, key}, state)
do
52 {:noreply , acc_delete(key, state, [])
}
53 end
54
55 def handle_info(_msg, state) do
56 {:noreply , state}
57 end
58
59 def terminate(:normal, _state) do
60 :ok
61 end
62
63 end
44 handle_cast({write, Key, Element}, State)
->
45 {noreply , [{Key, Element} | State]};
46 handle_cast({delete, Key}, State) ->
47 {noreply , lists:keydelete(Key, 1, State
)}.
48
49 handle_info(_Info, State) ->
50 {noreply , State}.
51
52 terminate(normal, _State) ->
53 ok.
12
SIMPLE DISTRIBUTION
13
SIMPLE INTEGRATION
14
15
ELIXIR, THE NOT-SO-HIDDEN PATH TO ERLANG
Concurrency & distribution
(+scalability, robustness...) made easy!
16
ELIXIR, THE NOT-SO-HIDDEN PATH TO ERLANG
Concurrency & distribution
(+scalability, robustness...) made easy!
Enjoy the power of the actor model
16
ELIXIR, THE NOT-SO-HIDDEN PATH TO ERLANG
Concurrency & distribution
(+scalability, robustness...) made easy!
Enjoy the power of the actor model
Take advantage of OTP & other tools
◦ Behaviours
◦ Static analysis, stateful property-based
testing, etc.
16
17
Thanks!
@lauramcastro
lcastro@udc.es
18

More Related Content

What's hot

Migrating to JUnit 5
Migrating to JUnit 5Migrating to JUnit 5
Migrating to JUnit 5
Rafael Winterhalter
 
The Magic Of Elixir
The Magic Of ElixirThe Magic Of Elixir
The Magic Of Elixir
Gabriele Lana
 
Rxjava2 custom operator
Rxjava2 custom operatorRxjava2 custom operator
Rxjava2 custom operator
彥彬 洪
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Fedor Lavrentyev
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and Utilities
Pramod Kumar
 
Google Guava
Google GuavaGoogle Guava
Google Guava
Alexander Korotkikh
 
Pure kotlin
Pure kotlinPure kotlin
Pure kotlin
Jarek Ratajski
 
Why Learn Python?
Why Learn Python?Why Learn Python?
Why Learn Python?
Christine Cheung
 
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorProgramming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Fedor Lavrentyev
 
Swift 2
Swift 2Swift 2
Swift 2
Jens Ravens
 
Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015
Iran Entrepreneurship Association
 
The Ring programming language version 1.5.3 book - Part 27 of 184
The Ring programming language version 1.5.3 book - Part 27 of 184The Ring programming language version 1.5.3 book - Part 27 of 184
The Ring programming language version 1.5.3 book - Part 27 of 184
Mahmoud Samir Fayed
 
Transaction is a monad
Transaction is a  monadTransaction is a  monad
Transaction is a monad
Jarek Ratajski
 
The core libraries you always wanted - Google Guava
The core libraries you always wanted - Google GuavaThe core libraries you always wanted - Google Guava
The core libraries you always wanted - Google Guava
Mite Mitreski
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
Anton Arhipov
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languages
Rafael Winterhalter
 
Java 8 - Nuts and Bold - SFEIR Benelux
Java 8 - Nuts and Bold - SFEIR BeneluxJava 8 - Nuts and Bold - SFEIR Benelux
Java 8 - Nuts and Bold - SFEIR Benelux
yohanbeschi
 
Google Guava
Google GuavaGoogle Guava
Google Guava
Scott Leberknight
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 Seasons
Baruch Sadogursky
 
Groovy 1.8の新機能について
Groovy 1.8の新機能についてGroovy 1.8の新機能について
Groovy 1.8の新機能について
Uehara Junji
 

What's hot (20)

Migrating to JUnit 5
Migrating to JUnit 5Migrating to JUnit 5
Migrating to JUnit 5
 
The Magic Of Elixir
The Magic Of ElixirThe Magic Of Elixir
The Magic Of Elixir
 
Rxjava2 custom operator
Rxjava2 custom operatorRxjava2 custom operator
Rxjava2 custom operator
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
 
Use of Apache Commons and Utilities
Use of Apache Commons and UtilitiesUse of Apache Commons and Utilities
Use of Apache Commons and Utilities
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
Pure kotlin
Pure kotlinPure kotlin
Pure kotlin
 
Why Learn Python?
Why Learn Python?Why Learn Python?
Why Learn Python?
 
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorProgramming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
 
Swift 2
Swift 2Swift 2
Swift 2
 
Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015
 
The Ring programming language version 1.5.3 book - Part 27 of 184
The Ring programming language version 1.5.3 book - Part 27 of 184The Ring programming language version 1.5.3 book - Part 27 of 184
The Ring programming language version 1.5.3 book - Part 27 of 184
 
Transaction is a monad
Transaction is a  monadTransaction is a  monad
Transaction is a monad
 
The core libraries you always wanted - Google Guava
The core libraries you always wanted - Google GuavaThe core libraries you always wanted - Google Guava
The core libraries you always wanted - Google Guava
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
 
Code generation for alternative languages
Code generation for alternative languagesCode generation for alternative languages
Code generation for alternative languages
 
Java 8 - Nuts and Bold - SFEIR Benelux
Java 8 - Nuts and Bold - SFEIR BeneluxJava 8 - Nuts and Bold - SFEIR Benelux
Java 8 - Nuts and Bold - SFEIR Benelux
 
Google Guava
Google GuavaGoogle Guava
Google Guava
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 Seasons
 
Groovy 1.8の新機能について
Groovy 1.8の新機能についてGroovy 1.8の新機能について
Groovy 1.8の新機能について
 

Similar to Elixir: the not-so-hidden path to Erlang

Scala ntnu
Scala ntnuScala ntnu
Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)
Cody Engel
 
The Ring programming language version 1.6 book - Part 29 of 189
The Ring programming language version 1.6 book - Part 29 of 189The Ring programming language version 1.6 book - Part 29 of 189
The Ring programming language version 1.6 book - Part 29 of 189
Mahmoud Samir Fayed
 
Dallas Scala Meetup
Dallas Scala MeetupDallas Scala Meetup
Dallas Scala Meetup
Abhishek Srivastava
 
The Ring programming language version 1.8 book - Part 32 of 202
The Ring programming language version 1.8 book - Part 32 of 202The Ring programming language version 1.8 book - Part 32 of 202
The Ring programming language version 1.8 book - Part 32 of 202
Mahmoud Samir Fayed
 
Specs2
Specs2Specs2
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
John De Goes
 
Functional Operations - Susan Potter
Functional Operations - Susan PotterFunctional Operations - Susan Potter
Functional Operations - Susan Potter
distributed matters
 
Ruby
RubyRuby
Spock: Test Well and Prosper
Spock: Test Well and ProsperSpock: Test Well and Prosper
Spock: Test Well and Prosper
Ken Kousen
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
David Rodenas
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
Pavlo Baron
 
Elixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental ConceptsElixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental Concepts
Héla Ben Khalfallah
 
Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1 Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1
Andrei Savu
 
Esoft Metro Campus - Certificate in java basics
Esoft Metro Campus - Certificate in java basicsEsoft Metro Campus - Certificate in java basics
Esoft Metro Campus - Certificate in java basics
Rasan Samarasinghe
 
7li7w devcon5
7li7w devcon57li7w devcon5
7li7w devcon5
Kerry Buckley
 
Introduction to Kotlin
Introduction to KotlinIntroduction to Kotlin
Introduction to Kotlin
Oswald Campesato
 
Front end fundamentals session 1: javascript core
Front end fundamentals session 1: javascript coreFront end fundamentals session 1: javascript core
Front end fundamentals session 1: javascript core
Web Zhao
 
Scala coated JVM
Scala coated JVMScala coated JVM
Scala coated JVM
Stuart Roebuck
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
Stéphane Wirtel
 

Similar to Elixir: the not-so-hidden path to Erlang (20)

Scala ntnu
Scala ntnuScala ntnu
Scala ntnu
 
Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)
 
The Ring programming language version 1.6 book - Part 29 of 189
The Ring programming language version 1.6 book - Part 29 of 189The Ring programming language version 1.6 book - Part 29 of 189
The Ring programming language version 1.6 book - Part 29 of 189
 
Dallas Scala Meetup
Dallas Scala MeetupDallas Scala Meetup
Dallas Scala Meetup
 
The Ring programming language version 1.8 book - Part 32 of 202
The Ring programming language version 1.8 book - Part 32 of 202The Ring programming language version 1.8 book - Part 32 of 202
The Ring programming language version 1.8 book - Part 32 of 202
 
Specs2
Specs2Specs2
Specs2
 
Orthogonal Functional Architecture
Orthogonal Functional ArchitectureOrthogonal Functional Architecture
Orthogonal Functional Architecture
 
Functional Operations - Susan Potter
Functional Operations - Susan PotterFunctional Operations - Susan Potter
Functional Operations - Susan Potter
 
Ruby
RubyRuby
Ruby
 
Spock: Test Well and Prosper
Spock: Test Well and ProsperSpock: Test Well and Prosper
Spock: Test Well and Prosper
 
Introduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicoxIntroduction to web programming for java and c# programmers by @drpicox
Introduction to web programming for java and c# programmers by @drpicox
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
Elixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental ConceptsElixir in a nutshell - Fundamental Concepts
Elixir in a nutshell - Fundamental Concepts
 
Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1 Guava Overview. Part 1 @ Bucharest JUG #1
Guava Overview. Part 1 @ Bucharest JUG #1
 
Esoft Metro Campus - Certificate in java basics
Esoft Metro Campus - Certificate in java basicsEsoft Metro Campus - Certificate in java basics
Esoft Metro Campus - Certificate in java basics
 
7li7w devcon5
7li7w devcon57li7w devcon5
7li7w devcon5
 
Introduction to Kotlin
Introduction to KotlinIntroduction to Kotlin
Introduction to Kotlin
 
Front end fundamentals session 1: javascript core
Front end fundamentals session 1: javascript coreFront end fundamentals session 1: javascript core
Front end fundamentals session 1: javascript core
 
Scala coated JVM
Scala coated JVMScala coated JVM
Scala coated JVM
 
Python postgre sql a wonderful wedding
Python postgre sql   a wonderful weddingPython postgre sql   a wonderful wedding
Python postgre sql a wonderful wedding
 

More from Laura M. Castro

Ola, ChatGPT... que carreira sería boa para min?
Ola, ChatGPT... que carreira sería boa para min?Ola, ChatGPT... que carreira sería boa para min?
Ola, ChatGPT... que carreira sería boa para min?
Laura M. Castro
 
IAs xerativas e nesgos de xénero
IAs xerativas e nesgos de xéneroIAs xerativas e nesgos de xénero
IAs xerativas e nesgos de xénero
Laura M. Castro
 
As intelixencias artificiais como xeradoras de cultura: exploración dos nesgo...
As intelixencias artificiais como xeradoras de cultura: exploración dos nesgo...As intelixencias artificiais como xeradoras de cultura: exploración dos nesgo...
As intelixencias artificiais como xeradoras de cultura: exploración dos nesgo...
Laura M. Castro
 
David vs. Goliat: lecciones aprendidas de una experiencia fallida de adopción...
David vs. Goliat: lecciones aprendidas de una experiencia fallida de adopción...David vs. Goliat: lecciones aprendidas de una experiencia fallida de adopción...
David vs. Goliat: lecciones aprendidas de una experiencia fallida de adopción...
Laura M. Castro
 
Why on Earth would I test if I have to just "Let it crash"?
Why on Earth would I test if I have to just "Let it crash"?Why on Earth would I test if I have to just "Let it crash"?
Why on Earth would I test if I have to just "Let it crash"?
Laura M. Castro
 
How the BEAM will change your mind
How the BEAM will change your mindHow the BEAM will change your mind
How the BEAM will change your mind
Laura M. Castro
 
Elixir vs Java
Elixir vs JavaElixir vs Java
Elixir vs Java
Laura M. Castro
 
So I used Erlang... is my system as scalable as they say it'd be?
So I used Erlang... is my system as scalable as they say it'd be?So I used Erlang... is my system as scalable as they say it'd be?
So I used Erlang... is my system as scalable as they say it'd be?
Laura M. Castro
 
Automatic generation of UML sequence diagrams from test counterexamples
Automatic generation of UML sequence diagrams from test counterexamplesAutomatic generation of UML sequence diagrams from test counterexamples
Automatic generation of UML sequence diagrams from test counterexamples
Laura M. Castro
 
Making property-based testing easier to read for humans
Making property-based testing easier to read for humansMaking property-based testing easier to read for humans
Making property-based testing easier to read for humans
Laura M. Castro
 
Erlang as a supporting technology for teaching Software Architecture
Erlang as a supporting technology for teaching Software ArchitectureErlang as a supporting technology for teaching Software Architecture
Erlang as a supporting technology for teaching Software Architecture
Laura M. Castro
 
A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...
A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...
A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...
Laura M. Castro
 
Experiencias Industriales con Programación Declarativa
Experiencias Industriales con Programación DeclarativaExperiencias Industriales con Programación Declarativa
Experiencias Industriales con Programación Declarativa
Laura M. Castro
 
Functional programming goes to Hollywood... and around the world!
Functional programming goes to Hollywood... and around the world!Functional programming goes to Hollywood... and around the world!
Functional programming goes to Hollywood... and around the world!
Laura M. Castro
 
Failover and takeover contingency mechanisms for network partition and node f...
Failover and takeover contingency mechanisms for network partition and node f...Failover and takeover contingency mechanisms for network partition and node f...
Failover and takeover contingency mechanisms for network partition and node f...
Laura M. Castro
 
Editing documents with LaTeX
Editing documents with LaTeXEditing documents with LaTeX
Editing documents with LaTeX
Laura M. Castro
 
Introdución á edición de textos con LaTeX
Introdución á edición de textos con LaTeXIntrodución á edición de textos con LaTeX
Introdución á edición de textos con LaTeX
Laura M. Castro
 
Edición de textos con LaTeX
Edición de textos con LaTeXEdición de textos con LaTeX
Edición de textos con LaTeX
Laura M. Castro
 
Edición de textos con LaTeX
Edición de textos con LaTeXEdición de textos con LaTeX
Edición de textos con LaTeX
Laura M. Castro
 
Improving software development using Erlang/OTP
Improving software development using Erlang/OTPImproving software development using Erlang/OTP
Improving software development using Erlang/OTP
Laura M. Castro
 

More from Laura M. Castro (20)

Ola, ChatGPT... que carreira sería boa para min?
Ola, ChatGPT... que carreira sería boa para min?Ola, ChatGPT... que carreira sería boa para min?
Ola, ChatGPT... que carreira sería boa para min?
 
IAs xerativas e nesgos de xénero
IAs xerativas e nesgos de xéneroIAs xerativas e nesgos de xénero
IAs xerativas e nesgos de xénero
 
As intelixencias artificiais como xeradoras de cultura: exploración dos nesgo...
As intelixencias artificiais como xeradoras de cultura: exploración dos nesgo...As intelixencias artificiais como xeradoras de cultura: exploración dos nesgo...
As intelixencias artificiais como xeradoras de cultura: exploración dos nesgo...
 
David vs. Goliat: lecciones aprendidas de una experiencia fallida de adopción...
David vs. Goliat: lecciones aprendidas de una experiencia fallida de adopción...David vs. Goliat: lecciones aprendidas de una experiencia fallida de adopción...
David vs. Goliat: lecciones aprendidas de una experiencia fallida de adopción...
 
Why on Earth would I test if I have to just "Let it crash"?
Why on Earth would I test if I have to just "Let it crash"?Why on Earth would I test if I have to just "Let it crash"?
Why on Earth would I test if I have to just "Let it crash"?
 
How the BEAM will change your mind
How the BEAM will change your mindHow the BEAM will change your mind
How the BEAM will change your mind
 
Elixir vs Java
Elixir vs JavaElixir vs Java
Elixir vs Java
 
So I used Erlang... is my system as scalable as they say it'd be?
So I used Erlang... is my system as scalable as they say it'd be?So I used Erlang... is my system as scalable as they say it'd be?
So I used Erlang... is my system as scalable as they say it'd be?
 
Automatic generation of UML sequence diagrams from test counterexamples
Automatic generation of UML sequence diagrams from test counterexamplesAutomatic generation of UML sequence diagrams from test counterexamples
Automatic generation of UML sequence diagrams from test counterexamples
 
Making property-based testing easier to read for humans
Making property-based testing easier to read for humansMaking property-based testing easier to read for humans
Making property-based testing easier to read for humans
 
Erlang as a supporting technology for teaching Software Architecture
Erlang as a supporting technology for teaching Software ArchitectureErlang as a supporting technology for teaching Software Architecture
Erlang as a supporting technology for teaching Software Architecture
 
A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...
A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...
A Backpack to go the Extra-Functional Mile (a hitched hike by the PROWESS pro...
 
Experiencias Industriales con Programación Declarativa
Experiencias Industriales con Programación DeclarativaExperiencias Industriales con Programación Declarativa
Experiencias Industriales con Programación Declarativa
 
Functional programming goes to Hollywood... and around the world!
Functional programming goes to Hollywood... and around the world!Functional programming goes to Hollywood... and around the world!
Functional programming goes to Hollywood... and around the world!
 
Failover and takeover contingency mechanisms for network partition and node f...
Failover and takeover contingency mechanisms for network partition and node f...Failover and takeover contingency mechanisms for network partition and node f...
Failover and takeover contingency mechanisms for network partition and node f...
 
Editing documents with LaTeX
Editing documents with LaTeXEditing documents with LaTeX
Editing documents with LaTeX
 
Introdución á edición de textos con LaTeX
Introdución á edición de textos con LaTeXIntrodución á edición de textos con LaTeX
Introdución á edición de textos con LaTeX
 
Edición de textos con LaTeX
Edición de textos con LaTeXEdición de textos con LaTeX
Edición de textos con LaTeX
 
Edición de textos con LaTeX
Edición de textos con LaTeXEdición de textos con LaTeX
Edición de textos con LaTeX
 
Improving software development using Erlang/OTP
Improving software development using Erlang/OTPImproving software development using Erlang/OTP
Improving software development using Erlang/OTP
 

Recently uploaded

Leveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and StandardsLeveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and Standards
Neo4j
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
Jakub Marek
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
Fwdays
 
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and BioinformaticiansBiomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Neo4j
 
Y-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PPY-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PP
c5vrf27qcz
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
Tatiana Kojar
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
DanBrown980551
 
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectorsConnector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
DianaGray10
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
saastr
 
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
Brandon Minnick, MBA
 
The Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptxThe Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptx
operationspcvita
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Precisely
 
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
Edge AI and Vision Alliance
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
Alex Pruden
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
AppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSFAppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSF
Ajin Abraham
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 

Recently uploaded (20)

Leveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and StandardsLeveraging the Graph for Clinical Trials and Standards
Leveraging the Graph for Clinical Trials and Standards
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
 
"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota"Choosing proper type of scaling", Olena Syrota
"Choosing proper type of scaling", Olena Syrota
 
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and BioinformaticiansBiomedical Knowledge Graphs for Data Scientists and Bioinformaticians
Biomedical Knowledge Graphs for Data Scientists and Bioinformaticians
 
Y-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PPY-Combinator seed pitch deck template PP
Y-Combinator seed pitch deck template PP
 
Skybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoptionSkybuffer SAM4U tool for SAP license adoption
Skybuffer SAM4U tool for SAP license adoption
 
5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides5th LF Energy Power Grid Model Meet-up Slides
5th LF Energy Power Grid Model Meet-up Slides
 
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectorsConnector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
Connector Corner: Seamlessly power UiPath Apps, GenAI with prebuilt connectors
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
 
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024
 
Choosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptxChoosing The Best AWS Service For Your Website + API.pptx
Choosing The Best AWS Service For Your Website + API.pptx
 
The Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptxThe Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptx
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
 
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
AppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSFAppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSF
 
Artificial Intelligence and Electronic Warfare
Artificial Intelligence and Electronic WarfareArtificial Intelligence and Electronic Warfare
Artificial Intelligence and Electronic Warfare
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 

Elixir: the not-so-hidden path to Erlang

  • 1. ELIXIR the not-so-hidden path to Erlang A Coruña, February 1st, 2018 Laura M. Castro Universidade da Coruña 1
  • 2. 2
  • 3. 3
  • 4. Born in 1986, released ’98 Concurrency-oriented ◦ Lightweight, isolated processes, message-passing communication Multiplatform VM Transparent distribution OTP behaviours Hot code swap 3
  • 5. Born in 1986, released ’98 Concurrency-oriented ◦ Lightweight, isolated processes, message-passing communication Multiplatform VM Transparent distribution OTP behaviours Hot code swap 3
  • 6. Born in 2011 Runs on the Erlang VM Can invoke Erlang code Born in 1986, released ’98 Concurrency-oriented ◦ Lightweight, isolated processes, message-passing communication Multiplatform VM Transparent distribution OTP behaviours Hot code swap 3
  • 8. Dynamic typing Variable rebinding Lazy collections Strings are not lists Pipeline operator Namespaces Polymorphism via protocols Dynamic typing Single assignment Eager evaluation 4
  • 9. Dynamic typing Variable rebinding Lazy collections Strings are not lists Pipeline operator Namespaces Polymorphism via protocols Dynamic typing Single assignment Eager evaluation 4
  • 10. 5
  • 11. HELLO, WORLD! 1 defmodule World do 2 3 def hello(who) do 4 IO.puts "Hello, #{inspect who}!" 5 end 6 7 end 1 -module(world). 2 3 -export([hello/1]). 4 5 hello(Who) -> 6 io:format("Hello, ~p!~n", [Who]). 6
  • 12. HELLO, WORLD! 1 defmodule World do 2 3 def hello(who) do 4 IO.puts "Hello, #{inspect who}!" 5 end 6 7 end 1 -module(world). 2 3 -export([hello/1]). 4 5 hello(Who) -> 6 io:format("Hello, ~p!~n", [Who]). 6
  • 13. HELLO, WORLD! 1 defmodule World do 2 3 def hello(who) do 4 IO.puts "Hello, #{inspect who}!" 5 end 6 7 end 1 -module(world). 2 3 -export([hello/1]). 4 5 hello(Who) -> 6 io:format("Hello, ~p!~n", [Who]). 6
  • 14. SIMPLE MODULE 1 defmodule Boolean do 2 @moduledoc """ 3 Simple pattern matching 4 """ 5 6 @doc """ 7 Operator ’not’. 8 9 ## Parameters 10 11 - value: boolean to be negated 12 13 """ 14 @spec b_not(boolean) :: boolean 15 def b_not(true), do: false 16 def b_not(false), do: true 17 18 @doc """ 19 Operator ’and’. 20 21 ## Parameters 22 23 - value1, value2: booleans to operate 24 25 """ 26 @spec b_and(boolean , boolean) :: boolean 27 def b_and(true, true), do: true 28 def b_and(_, _), do: false 1 %%% @doc Simple pattern matching 2 %%% @end 3 -module(boolean). 4 5 -export([b_not/1, b_and/2]). 6 7 %% @doc Operator ’not’. 8 %% @end 9 -spec b_not(Value :: boolean()) -> boolean(). 10 b_not(true) -> false; 11 b_not(false) -> true. 12 13 %% @doc Operator ’and’. 14 %% @end 15 -spec b_and(Value1 :: boolean(), 16 Value2 :: boolean()) -> boolean(). 17 b_and(true, true) -> 18 true; 19 b_and(Value1, Value2) -> 20 false. 7
  • 18. UNIT TESTS 1 ExUnit.start 2 3 defmodule BooleanTest do 4 @moduledoc """ 5 Simple pattern matching (tests) 6 """ 7 8 use ExUnit.Case 9 doctest Boolean 10 11 test "Boolean negation" do 12 assert Boolean.b_not(false) 13 refute Boolean.b_not(true) 14 end 15 16 test "Boolean AND" do 17 assert Boolean.b_and(true, true) 18 refute Boolean.b_and(true, false) 19 refute Boolean.b_and(false, true) 20 refute Boolean.b_and(false, false) 21 end 22 23 end 1 %%% @doc Simple pattern matching (tests) 2 %%% @end 3 -module(boolean_tests). 4 5 -include_lib("eunit/include/eunit.hrl"). 6 7 b_not_test() -> 8 ?assert(boolean:b_not(false)), 9 ?assertNot(boolean:b_not(true)). 10 11 b_and_test() -> 12 ?assert(boolean:b_and(true,true)), 13 ?assertNot(boolean:b_and(true,false)), 14 ?assertNot(boolean:b_and(false,true)), 15 ?assertNot(boolean:b_and(false,false)). 8
  • 20. SIMPLE MODULE (II) 1 defmodule Create do 2 @moduledoc """ 3 Creating lists 4 """ 5 6 def create(n) when n>0 do 7 acc_forward(1, n, []) 8 end 9 10 def reverse_create(n) when n>0 do 11 acc_backwards(n, 1, []) 12 end 13 14 def acc_forward(a, a, l), do: [a|l] 15 def acc_forward(a, b, l), do: acc_forward(a, b-1, [b|l]) 16 17 def acc_backwards(a, a, l), do: [a|l] 18 def acc_backwards(a, b, l), do: acc_backwards(a, b+1, [b|l]) 19 20 end 1 %%% @doc Creating lists 2 %%% @end 3 -module(create). 4 5 -export([create/1, reverse_create/1]). 6 7 create(N) when N>0 -> 8 acc_forward(1, N, []). 9 10 reverse_create(N) when N>0 -> 11 acc_backwards(N, 1, []). 12 13 acc_forward(A, A, L) -> [A | L]; 14 acc_forward(A, B, L) -> 15 acc_forward(A, B-1, [B | L]). 16 17 acc_backwards(A, A, L) -> [A | L]; 18 acc_backwards(A, B, L) -> 19 acc_backwards(A, B+1, [B | L]). 9
  • 21. PROPERTY-BASED TESTS 1 defmodule CreateProps do 2 @moduledoc """ 3 Creating lists (test properties) 4 """ 5 6 use ExUnit.Case 7 use PropCheck 8 doctest Create 9 10 property "List creation" do 11 forall i <- positive_integer() do 12 Create.create(i+1) == Enum.to_list (1..i+1) 13 end 14 end 15 16 property "Reverse list creation" do 17 forall i <- positive_integer() do 18 Create.reverse_create(i+1) == Enum. reverse(Enum.to_list(1..i+1)) 19 end 20 end 21 22 end 1 %%% @doc Creating lists (test properties) 2 %%% @end 3 -module(create_props). 4 5 -include_lib("proper/include/proper.hrl") . 6 -compile(export_all). 7 8 prop_create() -> 9 ?FORALL(I, positive_integer(), 10 create:create(I) == lists:seq(1, I)). 11 12 prop_reverse_create() -> 13 ?FORALL(I, positive_integer(), 14 create:reverse_create(I) == lists: reverse(lists:seq(1, I))). 10
  • 22. PROPERTY-BASED TESTS 1 defmodule CreateProps do 2 @moduledoc """ 3 Creating lists (test properties) 4 """ 5 6 use ExUnit.Case 7 use PropCheck 8 doctest Create 9 10 property "List creation" do 11 forall i <- positive_integer() do 12 Create.create(i+1) == Enum.to_list (1..i+1) 13 end 14 end 15 16 property "Reverse list creation" do 17 forall i <- positive_integer() do 18 Create.reverse_create(i+1) == Enum. reverse(Enum.to_list(1..i+1)) 19 end 20 end 21 22 end 1 %%% @doc Creating lists (test properties) 2 %%% @end 3 -module(create_props). 4 5 -include_lib("proper/include/proper.hrl") . 6 -compile(export_all). 7 8 prop_create() -> 9 ?FORALL(I, positive_integer(), 10 create:create(I) == lists:seq(1, I)). 11 12 prop_reverse_create() -> 13 ?FORALL(I, positive_integer(), 14 create:reverse_create(I) == lists: reverse(lists:seq(1, I))). 10
  • 26. SIMPLE PROCESS 1 defmodule DbProcess do 2 @moduledoc """ 3 Database handling using a process 4 """ 5 6 def new(), do: spawn(DbProcess , :loop, [[]]) 7 8 def write(key, element , dbref) do 9 send dbref, {:write, key, element} 10 dbref 11 end 12 13 def delete(key, dbref) do 14 send dbref, {:delete, key} 15 dbref 16 end 17 18 def read(key, dbref) do 19 send dbref, {:read, key, self()} 20 receive do 21 {_dbref, :found, element} -> {:ok, element} 22 {_dbref, :notfound} -> {: error, :instance} 23 end 24 end 1 %%% @doc Database handling using a process 2 %%% @end 3 -module(db_process). 4 5 -export([new/0, write/3, delete/2, read /2, match/2, destroy/1]). 6 7 new() -> 8 spawn(?MODULE, loop, [[]]). 9 10 write(Key, Element , DbRef) -> 11 DbRef ! {write, Key, Element}, 12 DbRef. 13 14 delete(Key, DbRef) -> 15 DbRef ! {delete, Key}, 16 DbRef. 17 18 read(Key, DbRef) -> 19 DbRef ! {read, Key, self()}, 20 receive 21 {DbRef, found, Element} -> {ok, Element}; 22 {DbRef, notfound} -> {error, instance} 23 end. 11
  • 27. SIMPLE PROCESS 25 def match(element , dbref) do 26 send dbref, {:match, element , self()} 27 receive do 28 {_dbref, keys} -> keys 29 end 30 end 31 32 def destroy(dbref) do 33 send dbref, :stop 34 :ok 35 end 24 match(Element , DbRef) -> 25 DbRef ! {match, Element , self()}, 26 receive 27 {DbRef, Keys} -> Keys 28 end. 29 30 destroy(DbRef) -> 31 DbRef ! stop, 32 ok. 11
  • 28. SIMPLE PROCESS 36 def loop(db) do 37 receive do 38 {:write, key, element} -> loop([{ key, element} | db]) 39 {:delete, key} -> loop( acc_delete(key, db, [])) 40 {:read, key, who} -> 41 case List.keyfind(db, key, 0) do 42 nil -> send who, { self(), :notfound} 43 {_key, element} -> send who, { self(), :found, element} 44 end 45 loop(db) 46 {:match, element , who} -> 47 keys = acc_match(element , db, []) 48 send who, {self(), keys} 49 loop(db) 50 :stop -> 51 :ok 52 end 53 end 33 loop(Db) -> 34 receive 35 {write, Key, Element} -> 36 loop([{Key, Element} | Db]); 37 {delete, Key} -> 38 loop(lists:keydelete(Key, 1, Db)); 39 {read, Key, Who} -> 40 case lists:keyfind(Key, 1, Db) of 41 false -> 42 Who ! {self(), notfound}; 43 {Key, Element} -> 44 Who ! {self(), found, Element} 45 end, 46 loop(Db); 47 {match, Element , Who} -> 48 Keys = acc_match(Element , Db, []), 49 Who ! {self(), Keys}, 50 loop(Db); 51 stop -> 52 ok 53 end. 11
  • 29. SIMPLE OTP PROCESS 1 defmodule DbGenServer do 2 @moduledoc """ 3 Database handling using OTP 4 """ 5 6 use GenServer 7 8 def new() do 9 GenServer.start_link(__MODULE__ , [], name: DbGenServer) 10 end 11 12 def write(key, element) do 13 GenServer.cast(DbGenServer , {:write, key, element}) 14 end 15 16 def delete(key) do 17 GenServer.cast(DbGenServer , {:delete, key}) 18 end 19 20 def read(key) do 21 GenServer.call(DbGenServer , {:read, key}) 22 end 1 %% @doc Database handling using OTP 2 %% @end 3 -module(db_gen_server). 4 -behaviour(gen_server). 5 6 -export([new/0, write/2, delete/1, read /1, match/1, destroy/0]). 7 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). 8 9 -define(SERVER, ?MODULE). 10 11 new() -> 12 gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). 13 14 write(Key, Element) -> 15 gen_server:cast(?SERVER, {write, Key, Element}). 16 17 delete(Key) -> 18 gen_server:cast(?SERVER, {delete, Key}) . 19 20 read(Key) -> 21 gen_server:call(?SERVER, {read, Key}). 12
  • 30. SIMPLE OTP PROCESS 23 def match(element) do 24 GenServer.call(DbGenServer , {:match, element}) 25 end 26 27 def destroy() do 28 GenServer.stop(DbGenServer) 29 end 30 31 ## GenServer Callbacks 32 33 def init([]) do 34 {:ok, []} 35 end 36 37 def handle_call({:read, key}, _from, state) do 38 reply = case List.keyfind(state, key, 0) do 39 nil -> {:error, :instance} 40 {_key, element} -> {:ok, element} 41 end 42 {:reply, reply, state} 43 end 44 def handle_call({:match, element}, _from, state) do 45 keys = acc_match(element , state, []) 46 {:reply, keys, state} 47 end 22 match(Element) -> 23 gen_server:call(?SERVER, {match, Element}). 24 25 destroy() -> 26 gen_server:stop(?SERVER). 27 28 % gen_server callbacks 29 30 init([]) -> 31 {ok, []}. 32 33 handle_call({read, Key}, _From, State) -> 34 Reply = case lists:keyfind(Key, 1, State) of 35 false -> 36 {error, instance}; 37 {Key, Element} -> 38 {ok, Element} 39 end, 40 {reply, Reply, State}; 41 handle_call({match, Element}, _From, State) -> 42 Keys = acc_match(Element , State, []), 43 {reply, Keys, State}. 12
  • 31. SIMPLE OTP PROCESS 48 def handle_cast({:write, key, element}, state) do 49 {:noreply , [{key, element} | state]} 50 end 51 def handle_cast({:delete, key}, state) do 52 {:noreply , acc_delete(key, state, []) } 53 end 54 55 def handle_info(_msg, state) do 56 {:noreply , state} 57 end 58 59 def terminate(:normal, _state) do 60 :ok 61 end 62 63 end 44 handle_cast({write, Key, Element}, State) -> 45 {noreply , [{Key, Element} | State]}; 46 handle_cast({delete, Key}, State) -> 47 {noreply , lists:keydelete(Key, 1, State )}. 48 49 handle_info(_Info, State) -> 50 {noreply , State}. 51 52 terminate(normal, _State) -> 53 ok. 12
  • 34. 15
  • 35. ELIXIR, THE NOT-SO-HIDDEN PATH TO ERLANG Concurrency & distribution (+scalability, robustness...) made easy! 16
  • 36. ELIXIR, THE NOT-SO-HIDDEN PATH TO ERLANG Concurrency & distribution (+scalability, robustness...) made easy! Enjoy the power of the actor model 16
  • 37. ELIXIR, THE NOT-SO-HIDDEN PATH TO ERLANG Concurrency & distribution (+scalability, robustness...) made easy! Enjoy the power of the actor model Take advantage of OTP & other tools ◦ Behaviours ◦ Static analysis, stateful property-based testing, etc. 16
  • 38. 17