Developer Freelance in Paris
o.gonthier@gmail.com
Gonthier Olivier
Team switch
Client side
Java
Android
IntelliJ
Server side
Erlang
MongooseIM
Vim
And also:
-Functional principles by learning Haskell
-Scrum-mastering, continuous integration
Online training
Read books
Watch talks
Read code
Oh, you want to use a dead language?
Java is better
Oh, you was doing ugly fat Java! Beh
Erlang is better
VM-based, Functional, impure,
Typed dynamically, Concurrent, Distributed,
Opinionated
Erlang is a general-purpose, concurrent, garbage-collected programming language and runtime system. (Wikipédia)
Created by Sony Ericsson in 1987
Open-Source since 1998
Facebook started his chat in erlang, dropped it for c++ in 2009, and then... Bought whatsapp, using erlang, 5 years later
-module(my_module).
-export([my_func/1, my_other_func/2, another_one/0]).
% A comment
%% A function returning its parameter
my_func(X) -> X.
%% A function using pattern matching
my_other_func(true, _) -> ok;
my_other_func(_, _) -> error.
%% A function with multiple clauses
another_one() ->
X = my_func(0),
Y = other_module:other_func(),
X+Y.
%% A function not exported
private_function() -> ok.
Java analogy
module = class; function = method; export = public
% Matching on function definition
invert(true) -> false;
invert(false) -> true.
% Values passed in parameter are bound
add_one(X) -> X+1.
% Pattern matching using case syntax
case write_file("helloworld") of
{ok, File} -> File;
{error, Error} -> log_error(Error)
end.
% Matching bind variables
> X = 1.
% Binding can be done even with data structures
> {Y, [Z, B]} = {2, [3, true]}
% Bounded variable can't match other values
> X = 2.
** exception error: no match of right hand side value 2
% No problems if trying to bind the same value
> {X, Y} = {1, 2}.
Boolean: true, false
Numbers: 1, 0.5, 2.0e3, $A, 2#101001
Atoms: hello, this_is_an_atom, ok
Tuples: {1, 2}, {temp, {celsius, 21}}
List: [1,2], [true, 1, ok, {beer, blond}]
Strings: "hello", [96,97,98]
Also: Binaries, PID, Fun, Map
Atoms are a kind of simple "tags"
In use, it can be similar to Java enums or static values.
public static final int DECEMBER = 12;
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
selectDay(25, SUNDAY, DECEMBER);
select_day(25, sunday, december).
They are often used to give context to values
{prices, [{beer, 2}, {vodka, 10}], euro}.
Beh.
> [104, 101, 108, 108, 111]
"hello"
> [X, Y] = "ab".
> X.
97
> [X, Y, 0].
[97, 98, 0]
Excuse me?
Alternative: bit strings
> <<"Hello world">>.
> <<A, B>> = <<"ab">>.
> A.
97
Lightweight processes, and Message Passing
-module(echo).
-export([go/0, loop/0]).
go() ->
Pid2 = spawn(echo, loop, []),
Pid2 ! {self(), hello},
receive
{Pid2, Msg} ->
io:format("P1 ~w~n",[Msg])
end,
Pid2 ! stop.
loop() ->
receive
{From, Msg} ->
From ! {self(), Msg},
loop();
stop ->
true
end.
Pid ! {MyPid, Msg} % Send message to Pid
-At the heart of the language-
Erlang VMs visible on network and sharing a specific cookie, are interconnected!
And you can send messages to other nodes transparently!
You can connect/disconnect nodes whenever you want
-Open Telecom Platform-
Abstract things we need often,
like server/client pattern
Supervision tree made easy
-behaviour(supervisor).
-behaviour(gen_server).
-behaviour(gen_event).
-behaviour(gen_fsm).
But recover from it
No need of defensive programming
Kill yourself if you can't recover.
Message passing
Share nothing
Kill people not respecting the protocol.
REPL
Debug Console
$> erl
% Compile a module
c(my_module).
% Unbind var
f(X).
Good News: Hot reloading is available in Erlang!
Thoughts
you don't need to reboot your app
static typing would have been complicated with this
Nothing to do, just compile and use your new .beam
Or Junit with a 'E' instead of 'J'
-module(fibo).
-ifdef(EUNIT).
-include_lib("eunit/include/eunit.hrl").
-endif.
fib(0) -> 1;
fib(1) -> 1;
fib(N) when N > 1 -> fib(N-1) + fib(N-2).
fib_test_() ->
[?_assert(fib(0) =:= 1),
?_assert(fib(1) =:= 1),
?_assert(fib(2) =:= 2),
?_assert(fib(3) =:= 3),
?_assert(fib(4) =:= 5),
?_assert(fib(5) =:= 8),
?_assertException(error, function_clause, fib(-1)),
?_assert(fib(31) =:= 2178309)
].
Maven/Gradle equivalent
$ rebar create-app appid=myapp
$ rebar get-deps
$ rebar compile
$ rebar eunit
$ rebar generate
Muptiple commands to compile/test/package etc.
{deps, [
{em, ".*", {git, "https://github.com/sheyll/erlymock.git"}},
{nano_trace, ".*", {git, "https://github.com/sheyll/nano_trace.git", {branch, "feature/rebar-migration"}}},
{mochiweb, "2.3.2", {git, "https://github.com/mochi/mochiweb.git", {tag, "v2.3.2"}}},
% Or specify a revision to refer a particular commit, useful if the project has only the master branch
% {mochiweb, "2.3.2", {git, "https://github.com/mochi/mochiweb.git", "15bc558d8222b011e2588efbd86c01d68ad73e60"},
% An example of a "raw" dependency:
{rebar, ".*", {git, "git://github.com/rebar/rebar.git", {branch, "master"}}, [raw]}
]}.
Configuration is done in a rebar.config file
Dependencies are git repositories :(
A very useful debug console
> observer:start().
Supervision tree, tracing, systems statistics, consumption...
Dialyzer: let you do a static analysis
Reltool: tool to make erlang releases
(used by rebar)
Erlang.mk: Alternative to rebar based on a makefile
WombatOAM: commercial product for system supervision
If you want to hear about a new name for Erlang...
Awesome book!
A good list of resources
https://gist.github.com/macintux/6349828
Gonthier Olivier
@rolios
o.gonthier@gmail.com