slides of the Erlang course

advertisement
Introduction to Erlang
Eddy Caron
2013
M1. ENS-Lyon
1
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Piece of History
1982 – 1985 Experiments with programming of telecom using > 20 different
languages. Conclusion: The language must be a very high level symbolic
language in order to achive productivity gains ! (Leaves us with: Lisp , Prolog ,
Parlog ...)
1985 – 86 Experiments with Lisp, Prolog, Parlog etc. Conclusion: The language
must contain primitives for concurrency and error recovery, and the execution
model must not have back-tracking. (Rules out Lisp and Prolog). We must
therefore develop our own language with the desirable features of Lisp, Prolog
and Parlog, but with concurrency and error recovery built into the language.
1987 The first experiments with Erlang.
1993 Distribution is added to Erlang, which makes it possible to run a
homgeneous Erlang system on a heterogeneous hardware. Decision to sell
implementations Erlang externally. Separate organization in Ericsson started to
maintain and support Erlang implementations and Erlang Tools.
2
Systèmes Distribués
Eddy Caron
Introduction to Erlang
The Erlang Shell
The Erlang Shell
[ecaron@aspen bin]$ ./erl
Erlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9.2 (abort with ^G)
1> 2+5.
7
2> (42+6)*33/4.
396.0
3> halt().
[ecaron@aspen bin]$
You can use Ctrl+c to break
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
3
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Hello world
‘%’ starts a comment
‘.’ ends a declaration
Every function must be in a module
one module per source file
source file name is module name + “.erl”
‘:’ used for calling functions in other modules
4
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Module and Functions
A programming language isn't much use if you can just
run code from the shell.
[ecaron@aspen Erlang]$ cat mult2.erl
-module(mult2).
-export([double/1]).
double(X) ->
2 * X.
use it
[ecaron@aspen Erlang]$ erl
Erlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernelpoll:false]
Compilation is ok !
Eshell V5.9.2 (abort with ^G)
1> c(mult2).
{ok,mult2}
2> mult2:double(6).
12
Systèmes Distribués
5
Eddy Caron
Introduction to Erlang
Numbers
Regular numbers
123
-34567
12.345
-27.45e-05
#-notation for base-N integers
1> 16#ff.
255
$-notation for character codes (ISO-8859-1)
2> $A.
65
6
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Atoms
Must start with lower case character or be quoted
friday
unquoted_atoms_cannot_contain_blanks
’A quoted atom with several blanks’
’hello \n my friend’
Similar to hashed strings
use only one word of data
constant-time equality test
7
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Tuples
Terms seprated by ‘,’ and enclosed in {}
{123, bcd}
{123, def, abc}
{person, 'Jax', ’Teller'}
{abc, {def, 123}, jkl}
{}
A fixed number of items (similar to structure or record in
conventional programming languages)
A tuple whose first element is an atom is called a tagged
tuple
8
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Other Data Types
Module:fun(Arg1,Arg2,… Argn)
Functions
Bin = <<Bin0,...>>
Binaries
1> spawn(m, f, []).
Process identifiers
<0.51.0>
References: A reference is a term which is unique
in an Erlang runtime system, created by calling
make_ref/0.
Erlang values in general are called « terms »
All terms are ordered and can be compared with
‘<’, ‘>’, ‘==’, ‘=:=’ , etc.
Systèmes Distribués
Eddy Caron
Introduction to Erlang
9
Recursive Functions
Variables start with upper-case characters
‘;’ separates function clauses
‘,’ separates instructions
Variables are local to the function clause
Pattern matching and guards to select clauses
10
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Recursive Functions
recurs.erl
-module(recurs).
-export([fac/1]).
fac(0) -> 1;
fac(N) -> N * fac(N-1).
Compile and run
[ecaron@aspen Erlang]$ erl
Erlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe]
[kernel-poll:false]
Eshell V5.9.2 (abort with ^G)
1> c(recurs).
{ok,recurs}
2> recurs:fac(6).
720
11
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Recursive Functions
dblfunc.erl
-module(dblfunc).
-export([fac/1, mult/2]).
fac(1) ->
1;
fac(N) ->
N * fac(N - 1).
mult(X, Y) ->
X * Y.
Compile and run
[ecaron@aspen Erlang]$ erl
Erlang R15B02 (erts-5.9.2) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9.2 (abort with ^G)
1> c(dblfunc).
{ok,dblfunc}
2> dblfunc:fac(4).
24
3> dblfunc:mult(dblfunc:fac(4),2).
48
Systèmes Distribués
12
Eddy Caron
Introduction to Erlang
Tail Recursion
The arity is part of the function name
Non-exported functions are local to the module
mylists.erl
-module(mylists).
-export([reverse/1]).
reverse(L) ->
reverse(L, []).
reverse([H|T], L) ->
reverse(T, [H|L]);
reverse([], L) ->
L.
> mylists:reverse([3,2,1]).
[1,2,3]
Systèmes Distribués
13
Eddy Caron
Introduction to Erlang
Tail Recursion
> mylists:reverse([1,2,3]).
[3,2,1]
reverse([1,2,3])
->
reverse([1,2,3],[]).
->
reverse([2,3],[1])
->
reverse([3],[2,1])
->
reverse([],[3,2,1])
->
[3,2,1]
mylists.erl
-module(mylists).
-export([reverse/1]).
reverse(L) ->
reverse(L, []).
reverse([H|T], L) ->
reverse(T, [H|L]);
reverse([], L) ->
L.
14
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Recursion over Lists
Pattern-matching selects components of the data
‘_’ is a “don’t care” pattern (not a variable)
‘[]’ is the empty list
‘[X,Y,Z]’ is a list with exactly three elements
‘[X,Y,Z|Tail]’ has three or more elements
15
Systèmes Distribués
Eddy Caron
Introduction to Erlang
List Recursion with Accumulator
The same syntax is used to construct lists
Strings are simply lists of character codes
Avoid adding data to the end of the list
16
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Built-in Functions
Implemented in C
All the type tests and conversions are BIFs
Most BIFs (not all) are in the module “erlang”
Many common BIFs are auto-imported
(recognized without writing “erlang:...”)
Operators (‘+’,’-’,’*’,’/’,...) are also really BIFs
Described in the BIFS manual
17
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Built-in Functions
Some examples
1> date().
{2012,10,23}
2> time().
{1,14,35}
3> length([1,2,3,4,5]).
5
4> size({a,b,c}).
3
5> atom_to_list(an_atom).
"an_atom"
6> list_to_tuple([1,2,3,4]).
{1,2,3,4}
7> integer_to_list(3412).
"3412"
8> tuple_to_list({}).
[]
18
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Standard Libraries
Application Libraries
Stdlib
Kernel
a.
b.
c.
d.
e.
erlang
code
file
inet
os
a.
b.
c.
d.
lists
dict
sets
...
19
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Expressions
Boolean and/or/xor are strict (always evaluate both
arguments)
Use andalso/orelse for short circuit evaluation
‘==’ for equality, not ‘=’
Always use parentheses when not absolutely
certain about the precedence
20
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Fun Expressions
1> Fun1 = fun (X) -> X+1 end.
#Fun<erl_eval.6.39074546>
2> Fun1(2).
3
3> Fun2 = fun (X) when X>=5 -> gt; (X) -> lt end.
#Fun<erl_eval.6.39074546>
4> Fun2(7).
gt
21
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Pattern Matching
Match failure causes run-time error
Successful matching binds the variables
but only if they are not already bound to a value
previously bound variables can be used in a pattern
a new variable can also be repeated in a pattern
-module(pm).
-export([mylength/1]).
mylength([]) -> 0;
mylength([_|T]) ->
mylength(T) + 1.
22
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Case-switches
Any number of clauses
Patterns and guards, just as in functions
‘;’ separates clauses
Use ‘_’ as catch-all
Variables may also begin with underscore
signals “I don’t intend to use this value”
is_valid_signal(Signal) ->
case Signal of
{signal, _What, _From, _To} ->
true;
{signal, _What, _To} ->
true;
_Else ->
false
end.
Systèmes Distribués
Eddy Caron
23
Introduction to Erlang
If-switches
Like a case-switch without the patterns and the ‘when’ keyword
Use ‘true’ as catch-all
factorial(N) when N == 0 -> 1;
factorial(N) when N > 0 ->
N * factorial(N - 1).
24
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Switching
If
Pattern Matching
factorial(N) ->
if
N == 0 -> 1;
N > 0 -> N * factorial(N - 1)
end.
factorial(0) -> 1;
factorial(N) ->
N * factorial(N-1).
When
Case
factorial(N) when N == 0 -> 1;
factorial(N) when N > 0 ->
N * factorial(N - 1).
factorial(N) -> 1
case (N) of
0 -> 1;
N when N > 0 -> N * factorial(N - 1)
end.
25
Systèmes Distribués
Eddy Caron
Introduction to Erlang
List and Tuple Processing
List Processing BIFs
List Processing Functions
member(X,L)
append(L1,L2)
reverse(L)
delete_all(X,L)
atom_to_list(A)
float_to_list(F)
integer_to_list(I)
tuple_to_list(T)
list_to_atom(L)
...
hd(L)
tl(L)
length(L)
Tuple Processing BIFS
tuple_to_list(T)
element(N,T)
setelement(N,T,Val)
size(L)
…
26
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Catching Exceptions
throw: user defined
error: runtime errors
exit: end process
only catch throw exceptions
normally
-module(catch_it).
-compile(export_all).
% An example of throw and catch
g(X) when X >= 13 ->
ok;
g(X) when X < 13 ->
throw({exception1, bad_number}).
% Throw in g/1
% Catch in start/1
start(Input) ->
case catch g(Input) of
{exception1, Why} ->
io:format("trouble is ~w ", [ Why ]);
NormalReturnValue ->
io:format("good input ~w ", [ NormalReturnValue ] )
end.
8> c(catch_it).
{ok,catch_it}
9> catch_it:start(12).
trouble is bad_number ok
10> catch_it:start(13).
good input ok ok
27
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Processes
Code is executed by a process
A process keeps track of the program pointer, the stack,
the variables values, etc.
Every process has a unique process identifier: PID
Processes are concurrent
Virtual machine layer processes
Preemptive multitasking
Little overhead (e.g. 100.000 processes)
Can use multiple CPUs on multiprocessor machines
28
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Concurrency
•
Several processes may use the same program code
at the same time
– each has own program counter, stack, and variables
–
programmer need not think about other processes
updating the variables
29
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Message Passing
•
“!” is the send operator
–
•
Messages are sent asynchronously
–
•
Pid of the receiver is used as the address
The sender continues immediately
Any value can be sent as a message
echo.erl
-module(echo).
-export([start/0,loop/0]).
start() ->
spawn(echo, loop, []).
loop() ->
receive {From, Message} ->
io:format("> echo: ~w Msg: ~w ~n", [self(), Message]),
From ! Message,
loop()
end.
Systèmes Distribués
Eddy Caron
1> c(echo).
{ok,echo}
2> Id=echo:start(),
2> Id ! {self(),hello}.
> echo: <0.38.0> Msg: hello
{<0.31.0>,hello}
30
Introduction to Erlang
Message Queues
•
Each process has a message queue (mailbox)
–
•
incoming messages are placed in the queue (no size
limit)
A process receives a message when it extracts it
from the mailbox
–
need not take the first message in the queue
31
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Receive a Message
•
receive-expressions are similar to case switches
–
–
–
•
patterns are used to match messages in the mailbox
messages in the queue are tested in order
only one message can be extracted each time
Selective receive
–
–
–
Patterns and guards permit message
selection
receive-clauses are tried in order
If no message matches, the process
suspends and waits for a new message
32
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Receive with Timeout
•
A receive-expression can have an after-part
–
•
can be an integer (milliseconds) or “infinity”
The process waits until a matching message arrives, or the timeout
limit is exceeded
–
soft real-time: no guarantees
sleep(T)- process suspends for T ms.
sleep(T) ->
receive
after T -> true
end.
suspend() - process suspends indefinitely.
suspend() ->
receive
after infinity -> true
end.
33
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Send and Reply
•
Pids are often included in messages (self()), so that the receiver can
reply to the sender
–
•
Message order
–
•
If the reply includes the Pid of the second process, it is easier for the first
process to recognize the reply
The only guaranteed message order is
when both the sender and the receiver are
the same for both messages (first-in, first- out)
Selecting Unordered Messages
–
Using selective receive, it is possible to choose which messages to accept,
even if they arrive in a different order
34
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Starting Processes
The “spawn” function creates a new process
• The new process will run the specified function
•
–
•
The spawn operation always returns immediately
The return value is the Pid of the “child”
35
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Ping Pong
tut16.erl
-module(tut16).
-export([start/0, ping/1, pong/0]).
ping(0) ->
pong ! finished,
io:format("ping finished~n", []);
ping(N) ->
pong ! {ping, self()},
receive
pong ->
io:format("Ping received pong~n", [])
end,
ping(N - 1).
pong() ->
receive
finished ->
io:format("Pong finished~n", []);
{ping, Ping_PID} ->
io:format("Pong received ping~n", []),
Ping_PID ! pong,
pong()
end.
start() ->
register(pong, spawn(tut16, pong, [])),
spawn(tut16, ping, [3]).
1> c(tut16).
{ok,tut16}
2> tut16:start().
Pong received ping
<0.39.0>
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong
ping finished
Pong finished
36
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Process Termination
•
Process Termination A process terminates
when:
–
it finishes the function call that it started with
a.
There is an exception that is not caught
•
All messages sent to a terminated process
will be thrown away
• Same Pid will not be used before long time
37
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Registered Processes
•
A process can be registered under a name
• Any process can send a message to a registered process,
or look up the Pid
• The Pid might change (if the process is restarted and reregistered), but the name stays the same
Pid = spawn(?MODULE, server, []),
register(myserver, Pid),
myserver ! Msg.
38
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Links and Exit Signals
•
Any two processes can be linked
–
•
When a process dies, an exit signal is sent to all linked
processes, which are also killed
–
•
normal exit does not kill other processe
If a process sets its trap_exit flag, all signals will be
caught and turned into normal messages
–
–
•
Links are always bidirectionnal
process_flag(trap_exit, true)
Signal is turned into message {‘EXIT’, Pid, ErrorTerm}
This way, a process can watch other processes
39
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Distribution
•
Running “erl” with the flag “-name xxx”
–
–
starts the Erlang network distribution system
Makes the virtual machine emulator a “node” (‘xxx@host.domain’)
•
Erlang nodes can communicate over the network (but must find
each other first)
• Possible to send a Pid from one node to another (Pids are unique
across nodes)
• You can send a message to any process through its Pid (even on
another node)
• You can run several Erlang nodes (with different names) on the
same computer
40
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Connecting Nodes
•
Nodes are connected the first time they try to
communicate
• The function “net_adm:ping(Node)” is the easiest
way to set up a connection between nodes
–
•
returns “pong” or “pang”
Send a message to a registered process using
–
“{Name,Node} ! Message”
41
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Running Remote Processes
•
Variants of the spawn function can start processes
directly on another node
• The module ‘global’ contains functions for
–
•
registering and using named processes over the whole
network of connected nodes
setting global locks
42
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Ports:Talking to the Outside
•
Talks to an external (or linked-in) C program
• A port is connected to the process that opened it
• The port sends data to the process in messages
• A process can send data to the port
43
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Conclusion
Try Erlang in practical session…
• … and send me your own conclusion
•
44
Systèmes Distribués
Eddy Caron
Introduction to Erlang
References
•
Special and greatful thanks to Franck Petit et Sebastien Tixeuil
• http://www.erlang.org
• http://en.wikibooks.org/wiki/Erlang_Programming
•
Use case pour normalien ;-)
–
–
Un Caml Light Distribué [Elkamel Merah , Allaoua Chaoui]
« … Pour l’extension concurrente de Caml Light nous proposons quelques
primitives avec une sémantique très simple en utilisant le modèle du langage
de programmation ERLANG. Le support de la création dynamique de
processus et de la communication asynchrone entre processus sont les deux
principales extensions du langage Caml Light. "
45
Systèmes Distribués
Eddy Caron
Introduction to Erlang
Download