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).

References:

mailto:feedback@acmqueue.com

Archives