Loading presentation...

Present Remotely

Send the link below via email or IM

Copy

Present to your audience

Start remote presentation

  • Invited audience members will follow you as you navigate and present
  • People invited to a presentation do not need a Prezi account
  • This link expires 10 minutes after you close the presentation
  • A maximum of 30 users can follow your presentation
  • Learn more about this feature in our knowledge base article

Do you really want to delete this prezi?

Neither you, nor the coeditors you shared it with will be able to recover it again.

DeleteCancel

Make your likes visible on Facebook?

Connect your Facebook account to Prezi and let your likes appear on your timeline.
You can change this under Settings & Account at any time.

No, thanks

ErlangVMGoto2013

No description
by

Erik Stenman

on 12 May 2014

Comments (0)

Please log in to add your comment.

Report abuse

Transcript of ErlangVMGoto2013

I
Can't do Erlang
0
+
-
=
9
8
7
1
2
3
4
5
6
c
Erlang
The right concurrency model.
Error & exception handling done right
Good libraries for the hard stuff
The right concurrency model
Lightweight processes
Message passing
Share nothing semantics
Don't stop the world GC
Monitors & Signals
You might loose
The fantastic Erlang syntax.

Probably the multicore advantage.

Most likely the guarantee that there
is no shared state being updated
behind your back.

Transparent types.
The shell.
Hot code upgrade?
If I Can't do Erlang
is all lost?
No, you can:

Model your program as
a SaaS component.

Use message passing and no shared state.

Go the Akka way. Build
OTP in your language
of choice.
Entrepreneurs with an idea
Let's build a
webservice!
A language makes you think
The most important aspect of Erlang
has nothing to do with all the clever
solutions in the implementation.

The most important aspect is that
makes you think of a problem in a
new way.

In a concurrent way.
The Erlang VM
or
How I Stopped Worrying
and Started Loving Parallel Programming

If you want to
build a scalable
(web)service
you want to do it in
a language which
helps you scale.
Erlang
Ability to leverage multi-core
God way to get great programmers.
The concept of processes is an integral part of Erlang.
No shared memory -- easier to program.
The Erlang Virtual machine (BEAM) has support for symmetric multiprocessing.
“Each year your sequential programs will go slower.
Each year your concurrent programs will go faster.”
Nice paradox:
The lack of Erlang programmers makes it easier for us to find great programmers.

There are many great C and Java programmers, I’m sure, but they are hidden by hordes of mediocre programmers.

Programmers who know a functional programming language are often passionate about programming.

Passionate programmers makes
Great Programmers
-- Joe Armstrong
Erlang the language
Functional
Single-assignment
Dynamically typed
Concurrent
Distributed
Message passing
Soft real-time
Fault tolerant
No sharing
Automatic Memory Management (GC)
Open Source
1982-1986 Experiments with existing languages
1986-1987: First experiments with own language
1988-1989: Internal use
1990-1998: Erlang sold as a product by Ericsson
1998: Open Source
2009: On github
Development still done mainly by Ericsson
Erlang is gaining popularity
Erlang History
F1
=
fun
() -> 42
end
.
42 =
F1
().

F2
=
fun
(
X
) ->
X
+ 1
end
.
11 =
F2
(10).

F3
=
fun
(
X
,
Y
) ->
{
X
,
Y
,
Z
}

end
.
F4
=
fun
({foo,
X
},
A
) ->

A
+
X
*
Y
;
({bar,
X
},
A
) ->

A
-
X
*
Y
;
(_,
A
) ->

A

end
.

F5
=
fun
f/3

F6
=
fun
mod:f/3
%% File: hello.erl
-module(hello).
-export([run/0]).
run() -> io:format(
"Hello, World!\n"
).
Developed by Ericsson, Sweden
How to write robust software?
Two machines
- concurrency/distribution/error handling
(after Danish mathematician A. K. Erlang.)
(foo@frodo)1>
X
=42.
42
(foo@frodo)2>
X
.
42
(foo@frodo)3>
X
=43.
** exception error: no match of right hand side value 43
(foo@frodo)4>
Supervisor trees
Hof on DB
QLC
What is Erlang?
(foo@frodo)4>

F
=
fun
(
X
,
Y
) ->
X
+
Y
end.
#Fun<erl_eval.12.113037538>
(foo@frodo)5>

F
(1,2).
3
(foo@frodo)6>

F
(1.0, 2).
3.0
(foo@frodo)7>

F
(
"1"
, 2).
** exception error: bad argument in an arithmetic expression
in operator +/2
called as

"1"

+ 2
Demo 1
Demo2
%%% DEMO 1
%%% Show code
cd ~; erl

S=demo:start_server().
W = demo:start_worker(S).
W2 = demo:start_worker(S).
S ! {broadcast, hi}.
W ! terminate.
exit(W2, kill).
S ! {broadcast, hi}.
exit(S, kill).
S ! {broadcast, hi}.
%%%-------------------------------------------------------------------
%%% File : demo.erl
%%% Author : Tobias Lindahl <tobias@klarna.se>
%%% Description : Small server/worker demo
%%%
%%% Created : 21 Apr 2010 by Tobias Lindahl <tobias@klarna.se>
%%%-------------------------------------------------------------------
-module(demo).
-export([start_server/0, start_worker/1]).

%%%-------------------------------------------------------------------
%%% Interface
start_server() -> spawn(fun server/0).
start_worker(Server) -> spawn(fun() -> worker(Server)end).

%%%-------------------------------------------------------------------
%%% Server
server() ->
process_flag(trap_exit, true),
out("I am the server\n", []),
server_loop([]).

server_loop(Pids) ->
receive
{register, NewPid} ->
link(NewPid),
out("The pid ~p has registered\n", [NewPid]),
server_loop(ordsets:add_element(NewPid, Pids));
{broadcast, What} ->
out("Broadcasting: ~p\n", [What]),
send_to_all(Pids, What),
server_loop(Pids);
all_pids ->
out("Currently registered pids: ~p\n", [Pids]),
server_loop(Pids);
terminate ->
send_to_all(Pids, terminate),
out("Server terminating\n", []);
{'EXIT', Who, Why} ->
out("Process ~p died with slogan ~p\n", [Who, Why]),
server_loop(ordsets:del_element(Who, Pids));
What ->
out("Server received: ~p\n", [What]),
server_loop(Pids)
end.

%%%-------------------------------------------------------------------
%%% Worker
%%%

worker(Server) ->
out("I am a worker\n"),
Server ! {register, self()},
worker_loop(Server).

worker_loop(Server) ->
receive
terminate ->
out("Worker terminating\n");
What ->
out("Worker received: ~p\n", [What]),
worker_loop(Server)
end.

%%%-------------------------------------------------------------------
%%% Util
%%%

out(What) ->
out(What, []).

out(What, Fmt) ->
timer:sleep(100),
io:format("~p: " ++ What, [self()| Fmt]).

send_to_all([Pid|Left], What) ->
Pid ! What,
send_to_all(Left, What);
send_to_all([], _What) ->
ok.
%% DEMO 2
%% Start two cmd:s
%% On first
"c:\Program Files (x86)\erl5.8.1\bin\erl" -sname foo
nodes().
%% On second
"c:\Program Files (x86)\erl5.8.1\bin\erl" -sname bar
net:ping('foo@frodo').
nodes().

S = rpc:call('foo@frodo', demo, start_server, []).
%% on (foo@frodo)1>
i().

%% on (bar@frodo)
W = demo:start_worker(S).
S ! {broadcast, hi}.
Hot code loading
Genserver
Atoms/symbolic programming
Hof map/fold
Mnesia
lm() -> [c:l(M) || M <- mm()].
mm() -> modified_modules().
modified_modules() ->
[M || {M, _} <- code:all_loaded(), module_modified(M) == true].

module_modified(Module) ->
case code:is_loaded(Module) of
{file, preloaded} -> false;
{file, Path} -> CompileOpts = proplists:get_value(compile, Module:module_info()),
CompileTime = proplists:get_value(time, CompileOpts),
Src = proplists:get_value(source, CompileOpts),
module_modified(Path, CompileTime, Src);
_ -> false
end.
module_modified(Path, PrevCompileTime, PrevSrc) ->
case find_module_file(Path) of
false -> removed;
ModPath -> case beam_lib:chunks(ModPath, ["CInf"]) of
{ok, {_, [{_, CB}]}} ->
CompileOpts = binary_to_term(CB),
CompileTime = proplists:get_value(time, CompileOpts),
Src = proplists:get_value(source, CompileOpts),
not ((CompileTime == PrevCompileTime) and (Src == PrevSrc));
_ -> false
end
end.
Demo
cd("C:/Users/happi").
toolbar:start().
%% Klick on Kernel
%% OPen supervisor tree
sup:start().
%% Kill process
%% Kill supervisor
-module(sup).
-behaviour(supervisor).
-export([init/1]).
-export([start/0, start/1]).
-export([loop/1]).
%% Supervisor
init(_) ->
{ok, {{one_for_one, 1,60},
[{sup, {sup, start, [0]},
permanent, brutal_kill, worker, [sup]}]}}.

start() ->
%% {ok, P} = supervisor:start_link(sup, [0]),
supervisor:start_child(kernel_safe_sup,
{mysup, {supervisor,start_link, [sup,[0]]},
permanent, 2000, supervisor, [sup]}
).
%% Worker
start(Count) ->
io:fwrite("Starting...~n"),
Pid=spawn_link(fun() -> loop(Count) end),
{ok, Pid}.

loop(Count) ->
io:format("counting: ~p.~n", [Count]),
timer:sleep(1000),
loop(Count + 1).
Fault tolerant
%%%-------------------------------------------------------------------
%%% File : demo.erl
%%% Author : Tobias Lindahl <tobias@klarna.se>
%%% Description : Small server/worker demo
%%%
%%% Created : 21 Apr 2010 by Tobias Lindahl <tobias@klarna.se>
%%%-------------------------------------------------------------------
-module(demo).
-export([start_server/0, start_worker/1]).

%%%-------------------------------------------------------------------
%%% Interface
start_server() -> spawn(fun server/0).
start_worker(Server) -> spawn(fun() -> worker(Server)end).

%%%-------------------------------------------------------------------
%%% Server
server() ->
process_flag(trap_exit, true),
out("I am the server\n", []),
server_loop([]).

server_loop(Pids) ->
receive
{register, NewPid} ->
link(NewPid),
out("The pid ~p has registered\n", [NewPid]),
server_loop(ordsets:add_element(NewPid, Pids));
{broadcast, What} ->
out("Broadcasting: ~p\n", [What]),
send_to_all(Pids, What),
server_loop(Pids);
all_pids ->
out("Currently registered pids: ~p\n", [Pids]),
server_loop(Pids);
terminate ->
send_to_all(Pids, terminate),
out("Server terminating\n", []);
{'EXIT', Who, Why} ->
out("Process ~p died with slogan ~p\n", [Who, Why]),
server_loop(ordsets:del_element(Who, Pids));
What ->
out("Server received: ~p\n", [What]),
server_loop(Pids)
end.

%%%-------------------------------------------------------------------
%%% Worker
%%%

worker(Server) ->
out("I am a worker\n"),
Server ! {register, self()},
worker_loop(Server).

worker_loop(Server) ->
receive
terminate ->
out("Worker terminating\n");
What ->
out("Worker received: ~p\n", [What]),
worker_loop(Server)
end.

%%%-------------------------------------------------------------------
%%% Util
%%%

out(What) ->
out(What, []).

out(What, Fmt) ->
timer:sleep(100),
io:format("~p: " ++ What, [self()| Fmt]).

send_to_all([Pid|Left], What) ->
Pid ! What,
send_to_all(Left, What);
send_to_all([], _What) ->
ok.
%% DEMO 2
%% Start two terminals
%% On first
erl -sname foo
nodes().
%% On second
erl -sname bar
net:ping('foo@Eriks-MacBook-Air').
nodes().

S = rpc:call('foo@Eriks-MacBook-Air', demo, start_server, []).
%% on (foo@Eriks-MacBook-Air)1>
i().

%% on (bar@Eriks-MacBook-Air)
W = demo:start_worker(S).
S ! {broadcast, hi}.
Demo3
SPJ
Lennart
Phil
John
Binary and bit syntax
{‘FOR1’:4
SIZE:4
‘BEAM’:4
[{CHUNKNAME:4
CHUNKSIZE:4
[CHUNKDATA:1]:CHUNKSIZE
[4-BYTEPAD:1]:0-3
}
]:SIZE-4
}
Demo4
Definition of Beam file format.
Erik Stenman
Programming since 1980
Erlang since 1994
First native code compiler for Erlang
HiPE
Project Manager for Scala 1.0
2005-2010 CTO @ Klarna
Chief Scientist @ Klarna
Writing a book about the Erlang VM
Happi
This is what success looks like!
Today's Most Boring Talk
I don't like opinions!
I try to have only three:
1. Don't have opinions.
2. XSLT sucks is not that god.
3. Operator overloading is bad.
xxxxx
I will barely show any code.
Now Imagine this!
You
where
happy
here
But this is pain
2011

Questions?
Conclusion:
The future
looks bright!
Remember
I don't have
opinions
this is all
facts.

Weird but efficient strings
for I/O
Error & exception handling done right
Symbolic and transparent data structures
An interactive shell

Good libraries for the hard stuff
+ Preemptive multitasking
implemented through
reduction counting
A Process is just memory
In reality it is a bit more complicated
~80 words
~ 233 words
PCB
M-box
Stack
Heap
0 words
Dynamically & Strongly
Typed
Enables:
Hot code loading
Movable heaps & stacks
Transparency of data
Garbage Collection
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
Old
Heap
mbuf
mbuf
mbuf
mbuf
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
P1
P2
"Hello"
say_hello(P) -> P ! "Hello".
wait_and_listen() ->
receive
42 -> ok;
after 1000 -> ok
end,
receive
S -> S
end,
S.
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
P1
P2
"Hello"
say_hello(P) -> P ! "Hello".
wait_and_listen() ->
receive
42 -> ok;
after 1000 -> ok
end,
receive
S -> S
end,
S.
"Hello"
m-buf
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
P1
P2
"Hello"
say_hello(P) -> P ! "Hello".
wait_and_listen() ->
receive
42 -> ok;
after 1000 -> ok
end,
receive
S -> S
end,
S.
"Hello"
m-buf
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
P1
P2
"Hello"
say_hello(P) -> P ! "Hello".
wait_and_listen() ->
receive
42 -> ok;
after 1000 -> ok
end,
receive
S -> S
end,
S.
"Hello"
m-buf
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
PCB
Seen
m-box
Inbox
Stack
Heap
Free
PD
P1
P2
"Hello"
say_hello(P) -> P ! "Hello".
wait_and_listen() ->
receive
42 -> ok;
after 1000 -> ok
end,
receive
S -> S
end,
S.
"Hello"
Supervisor
Child
Supervisor
Child
Supervisor
Child
Child
Child
Child
Error & exception handling done right
get_file(FN) ->
try file:open(FN) of
{ok, FileH} ->
try read(FileH) of
{ok, File} -> File
catch
error:eof -> []
after
file:close(FileH)
end
end.
Symbolic and transparent data structures
any()
number()
atom()
reference()
fun() port() pid() tuple() list() binary()
nil() cons()
integer()
float()
none()
All values are tagged, some are boxed.
Erlang type lattice:
ADR BINARY VALUE + DESCRIPTION
hend -> +-------- -------- -------- --------+
| ... |
| ... |
|00000000 00000000 00000000 10000001| 128 + list tag ---------------+
stop -> | | |
|
htop -> | | |
132 |00000000 00000000 00000000 01111001| 120 + list tag -------------- | -+
128 |00000000 00000000 00000110 10001111| (H) 104 bsl 4 + small int tag <+ |
124 |00000000 00000000 00000000 01110001| 112 + list tag ----------------- | -+
120 |00000000 00000000 00000110 01011111| (e) 101 bsl 4 + small int tag <---+ |
116 |00000000 00000000 00000000 01110001| 112 + list tag -------------------- | -+
112 |00000000 00000000 00000110 11001111| (l) 108 bsl 4 + small int tag <------+ |
108 |00000000 00000000 00000000 01110001| 96 + list tag ----------------------- | -+
104 |00000000 00000000 00000110 11001111| (l) 108 bsl 4 + small int tag <---------+ |
100 |11111111 11111111 11111111 11111011| NIL |
96 |00000000 00000000 00000110 11111111| (o) 111 bsl 4 + small int tag <------------+
| ... |
heap -> +-----------------------------------+
Stack
Heap
DISCLAIMER
OTP
gen_server

supervisor

gen_fsm
I/O lists: A nested list of binaries and strings.
Strings are just list of integers.
Can be iso8859 characters or unicode codepoints.
String concatenation takes constant time:
concat(S1,S2) -> [S1,S2].
Fantastic for operation and maintenance:
1> lists:foldl(
fun ({_,V}, Acc) -> V + Acc end,
0,
[process_info(P, heap_size)
|| P <- processes()]).
46813
2>
Fantastic for prototyping and testing during development
Drawback: Erlang developers don't save their test driven development tests.
Erlang
Fault Tolerant, Maintainable
& Scalable
Fault Tolerant
Erlang
Dynamically typed.
Symbolic and transparent data structures
An interactive shell
Maintainable
Erlang
The right concurrency model.
Good libraries for the hard stuff
Weird but efficient strings for I/O
Scalable
The String "Hello"
It's
how
you think!
PS.
I might have lied in the disclaimer
in the beginning.
Full transcript