Erlang

Appeared in:
1986
Influenced by:
Influenced:
Paradigm:
Typing discipline:
File extensions:
.erl .ebin .escript
Versions and implementations (Collapse all | Expand all):
Programming language

Erlang (named after Danish mathematician Agner Krarup Erlang) is a functional concurrency-oriented general-purpose language designed for highly robust and continuously running systems.

An Erlang program is structured as a collection of lightweight concurrent processes that communicate with one another via message passing. Robustness is supported by means of a supervision strategy in which a certain process, termed a supervisor, monitors other processes and will restart them if they happen to crash. A running Erlang system is itself a collection of Erlang nodes which may be running on a single machine, a cluster of machines, or even on geographically remote machines.

Elements of syntax:

Inline comments %
Case-sensitivity case sensitive
Variable identifier regexp _?[A-Z][A-Za-z0-9_]*
Function identifier regexp [a-z][A-Za-Z0-9_]*
Variable assignment Variable = value.
Grouping expressions ( ... )
Function definition functionname(Arg1, ...) -> body.
Function call modulename:functionanme(Arg1, Arg2, ..., ArgN).
If - then if Guard1 -> Statements1; Guard2 -> Statements2; ... true -> DefaultStatements.
Loop forever tail_recursive_function() -> tail_recursive_function().

Examples:

Hello, World!:

Example for versions erl 5.7.3

First line notes that this module must be placed in file called prog.erl. Second line exports function main, of arity 0 (takes no parameters). Third line defines the function: all it does is output “Hello, World!”.

-module(prog).
 
-export([main/0]).
 
main() -> io:format("Hello, World!~n").

Factorial:

Example for versions erl 5.7.3

This example uses recursive factorial definition. Note that Erlang has no built-in loops, so the example uses a recursive function which starts with larger values of N, but calls itself for N-1 before printing N!. loop(_) is a clause that defines evaluation of loop() when its argument is not an integer or is negative; it is necessary for a proper function definition.

-module(prog).
 
-export([main/0, loop/1]).
 
fact(0) -> 1;
fact(N) -> N * fact(N-1). 
 
loop(N) when is_integer(N), N>=0 -> 
    loop(N-1),
    io:format("~B! = ~B~n",[N,fact(N)]);
loop(_) -> ok.
 
main() -> loop(16).

Fibonacci numbers:

Example for versions erl 5.7.3

This example uses iterative definition of Fibonacci numbers, expressed as tail recursion (each number is calculated only once).

-module(prog).
 
-export([main/0]).
 
fib(1,_,Res) -> 
    io:format("~B, ",[Res]);
fib(N,Prev,Res) when N > 1 -> 
    io:format("~B, ",[Res]),
    fib(N-1, Res, Res+Prev).
 
main() -> 
    fib(16,0,1),
    io:format("...~n").

Fibonacci numbers:

Example for versions erl 5.7.3

This example uses Binet’s formula to calculate Fibonacci numbers. The doubles have to be printed with at least one decimal digit, so the output looks like this:

1.0, 1.0, 2.0, 3.0, 5.0, 8.0, 13.0, 21.0, 34.0, 55.0, 89.0, 144.0, 233.0, 377.0, 610.0, 987.0, ...

-module(prog).
 
-export([main/0]).
 
fib(0) -> ok;
fib(N) -> 
    fib(N-1),
    SQ5 = math:sqrt(5),
    T1 = math:pow(0.5*(1 + SQ5),N),
    T2 = math:pow(0.5*(1 - SQ5),N),
    io:format("~.1f, ", [(T1-T2)/SQ5]).
    
main() ->
    fib(16),
    io:format("...~n").

Quadratic equation:

Example for versions erl 5.7.3

fread function can return several values: eof to mark that the input stream has ended, tuple {ok, value} if the read succeeded, and tuple {error, message} if it failed for any other reason. Thus, when a number is read, it has to be extra processed to stripe it of these things.

-module(prog).
 
-export([main/0]).
 
solve(A, B, C) -> 
    D = B*B - 4*A*C,
    if (D == 0) -> io:format("x = ~f~n", [-B*0.5/A]);
    true -> 
        if (D > 0) -> 
                SQ = math:sqrt(D),
                io:format("x1 = ~f~nx2 = ~f", [(-B+SQ)/2/A, (-B-SQ)/2/A]);
        true -> SQ = math:sqrt(-D),
                io:format("x1 = (~f,~f)~nx2 = (~f,~f)", [-0.5*B/A, 0.5*SQ/A, -0.5*B/A, -0.5*SQ/A])
        end
    end
.
    
main() -> 
    case io:fread("A = ", "~d") of
    eof -> true;
    {ok, X} ->
        [A] = X,
        if (A == 0) -> io:format("Not a quadratic equation.");
        true -> 
        case io: fread("B = ", "~d") of
            eof -> true;
            {ok, Y} ->
                [B] = Y,
                case io: fread("C = ", "~d") of
                eof -> true;
                {ok, Z} -> 
                     [C] = Z,
                     solve(A, B, C)
                end
            end
        end
    end.