Sean's Blog

Erlang

Erlang is a powerful functional programming language invented in Sweden at Ericsson in 1987, that excels at concurrency and fault-tolerance. Erlang processes are light-weight and share no memory and thus can scale easily across machines and CPU cores. Processes communicate via messages which are received in a queue that is pattern matched against the state loop (actor model). The process supervision tree allows fine-grained error management (let it crash), leading to robust production-ready apps.

Erlang is not made for math heavy computations though but can easily call C or other faster languages for that.

The ErlangVM (BEAM) powers big apps like WhattsApp and Discord, demonstrating its commercial viability.

Show me some code

Quicksort using list comprehension:

quicksort([]) -> [];
quicksort([Pivot | T]) ->
    quicksort([X || X <- T, X < Pivot]) ++
    [Pivot] ++
    quicksort([X || X <- T, X >= Pivot]).

Fibonacci:

-module(fibo).
-author("Sean Pedersen").
-compile(export_all).

% Head recursion (inefficient: builds up exponentially growing function call stack: 2^N)
fib(1) -> 1;
fib(2) -> 1;
fib(N) when N > 1 -> fib(N-1) + fib(N-2).

% Tail recursion (efficient: behaves like a loop)
% The tail recursive optimization lets the function call stack not grow at all)
fib_(N) -> fib(N, 0, 1).
fib(1, _First, Second) -> Second;
fib(N, First, Second) when N > 1 -> fib(N-1, Second, First+Second).

Message passing:

% Ping pong across two machines/nodes in the same local network
% pingpong.erl must be compiled in working dir of the erlang shells on both machines!
% ---STARTUP INSTRUCTIONS---
% node1:
% $ erl -compile pingpong
% $ erl -sname pong -setcookie we_have_cookies
% node2:
% $ erl -compile pingpong
% $ erl -sname ping -setcookie we_have_cookies
% pong@node2> pingpong:start(ping@welle).

-module(pingpong).
-export([start/1,  ping/3, pong/0]).

ping(0, PongName, PongNode) ->
    {PongName, PongNode} ! finished,
    io:format("Ping finished~n", []);

ping(N, PongName, PongNode) ->
    {PongName, PongNode} ! {ping, self()},
    receive
        pong ->
            io:format("Ping received pong~n", [])
    end,
    ping(N - 1, PongName, PongNode).

pong() ->
    receive
        finished ->
            io:format("Pong finished~n", []);
        {ping, PingPID} -> % Note that PingPID is enough to reply (PID contains info about its node)
            io:format("Pong received ping~n", []),
            PingPID ! pong,
            pong()
    end.

start(PingNode) ->
    PongName = pong,
    register(PongName, spawn(pingpong, pong, [])),
    % Spawn function ping/3 remotely on PingNode machine
    spawn(PingNode, pingpong, ping, [3, PongName, node()]).

Modern Dialects

Elixir and Gleam are notable modern dialects of Erlang that transpile straight to Erlang. Elixir offers syntactic sugar and a thriving open-source community with popular frameworks like Phoenix. Gleam is a type-safe alternative.

References

#programming