Erlang
for Concurrent Programming
to find the first match, then the body (after the arrow) is
evaluated. The value of the final expression in the body
is the return value of the call; no explicit return statement is needed. Erlang is dynamically typed, so a call to
factorial(“pancake”) will compile but will raise a runtime
exception when it fails to match any clause. Tail-calls are
optimized, so this code will run in constant space.
Lists are enclosed in square brackets (see figure 1B). A
• The model of concurrency is natural to
think about and requires no mathematical sophistication.
• The environment makes failures
detectable and recoverable, making it
possible to deploy a less-than-perfect
system in the field that can nonetheless maintain high availability.
• The concurrency model maps naturally
to distributed deployments.
This article introduces the Erlang
language and shows how it can be used
in practice to implement concurrent
programs correctly and quickly.
A
example1.erl
1
-module(example1).
-export([factorial/1, qsort/1, member/2, foldl/3, sum/1]).
Compute the factorial of a positive integer.
factorial(N) when is_integer(N), N > 0 -> factorial(N, 1).
A helper function which maintains an accumulator.
factorial( 1, Acc) -> Acc;
factorial(N, Acc) when N > 1 -> factorial(N - 1, N Acc).
SEQUENTIAL ERLANG
Erlang is built from a small number of
sequential programming types and concepts, and an even smaller number of
concurrent programming types and concepts. Those who want a full introduction can find several excellent tutorials
on the Web, 3 but the following examples
(required by functional programming
union regulations) should convey the
essentials.
As shown in figure 1A, every file of
Erlang code is a module. Declarations
within the file name the module (which
must match the filename) and declare
which functions can be called from
other modules. Comments run from the
percent sign (%) to the end of the line.
Factorial is implemented by two functions. Both are named factorial, but they
have different numbers of arguments;
hence, they are distinct. The definition
of factorial/2 (the two-argument version)
is split into two clauses, separated by a
semicolon. When factorial/2 is called,
the actual parameters are tested against
the patterns in each clause head in turn
B
Return a sorted copy of a list.
qsort([]) -> [];
qsort([Pivot | Xs]) ->
qsort([X || X <- Xs, X < Pivot])
++ [Pivot]
++ qsort([X || X <- Xs, X >= Pivot]).
C
Is X an element of a binary search tree?
member(_, empty) -> false;
member(X, {_, X, _}) -> true;
member(X, {Left, Y, _}) when X < Y -> member(X, Left);
member(X, {_, _, Right}) -> member(X, Right).
D
“Fold” a function across elements of a list, seeding
with an initial value.
% e.g. foldl(F, A0, [A, B, C]) = F(C, F(B, F(A, A0)))
foldl(_, Acc, []) -> Acc;
foldl(F, Acc, [X | Xs]) ->
NewAcc = F(X, Acc),
foldl(F, NewAcc, Xs).
Give the sum of a list of numbers.
sum(Numbers) -> foldl(fun(N, Total) -> N + Total end, 0, Numbers).