2026-03-24
erlang
My AI generated notes on Erlang for re-learning purposes.
This guide covers all the core topics you'll find on the official Erlang/OTP documentation but in a much shorter, "cheat‑sheet" style. Use it as a quick reference or a refresher before diving into projects.
1. Introduction
- What is Erlang? A functional, concurrent language created by Ericsson (1986). It runs on the BEAM virtual machine and is the foundation for fault‑tolerant distributed systems.
- Why learn Erlang?
- Lightweight processes (
spawn) and message passing → massive concurrency. - Hot code swapping & zero‑downtime upgrades.
- Mature OTP framework for building reliable applications.
- Lightweight processes (
2. Program Structure
-module(hello).
-export([start/0]).
start() ->
io:format("Hello, Erlang!~n"). -moduledeclares the module name (must match filename).-exportlists functions available outside the module.- Functions end with a period
.; clauses separated by semicolons;.
3. Syntax Basics
| Element | Example | Notes |
|---|---|---|
| Comments | % this is a comment | Single‑line, starts with %. |
| Atoms | ok, 'my atom' | Immutable constants; lowercase or quoted. |
| Variables | X = 42 | Must start with uppercase or _; single‑assignment. |
| Semicolon | foo(1) -> a; foo(_) -> b. | Separates function clauses. |
4. Variables & Data Types
| Type | Example | Notes |
|---|---|---|
integer | 42, -7, 16#FF | Arbitrary precision; hex with 16#. |
float | 3.14, 1.0e-3 | 64‑bit IEEE 754. |
atom | ok, error, true | Immutable named constant. |
boolean | true, false | Special atoms. |
string | "hello" | List of Unicode code points. |
binary | <<"hello">> | Efficient byte sequence. |
list | [1, 2, 3] | Linked list; head/tail with `[H |
tuple | {ok, Value} | Fixed‑size, heterogeneous. |
map | #{key => val} | Key‑value store (Erlang 17+). |
Tip: Use
erlang:type_of/1or pattern matching to inspect types at runtime.
5. Operators
| Category | Symbols | Example |
|---|---|---|
| Arithmetic | + - * / div rem | X = A + B, 7 div 2 → 3 |
| Assignment | = | X = 42 (pattern match / bind) |
| Comparison | == /= =:= =/= < > =< >= | A =:= B (exact equality) |
| Logical | and or not andalso orelse | true andalso false |
| Bitwise | bsl bsr bor band bxor bnot | 1 bsl 3 → 8 |
| List | ++ -- | [1,2] ++ [3] → [1,2,3] |
Note:
==does type coercion (1 == 1.0istrue);=:=is strict.
6. Booleans
Erlang's only boolean values are the atoms true and false.
Flag = true,
if
Flag -> io:format("yes~n");
true -> io:format("no~n") % 'true' acts as else
end. - Use
andalso/orelsefor short‑circuit evaluation in guards.
7. Conditional Statements
case
case Score of
S when S >= 90 -> io:format("A~n");
S when S >= 80 -> io:format("B~n");
_ -> io:format("C~n")
end. if
if
X > 0 -> positive;
X =:= 0 -> zero;
true -> negative
end. - Every
ifbranch must match; usetrueas a catch‑all (likeelse). caseis generally preferred overiffor readability.
8. Recursion & Loops
Erlang has no traditional loop constructs — use recursion instead:
print_n(0) -> ok;
print_n(N) when N > 0 ->
io:format("~p~n", [N]),
print_n(N - 1). Tail‑recursive version for large N (stack‑safe):
sum(N) -> sum(N, 0).
sum(0, Acc) -> Acc;
sum(N, Acc) when N > 0 ->
sum(N - 1, Acc + N). lists:foreach/2andlists:map/2replace many imperative loops.break/continuehave no equivalent — redesign with recursion or list functions.
9. Lists & Tuples
Nums = [1, 2, 3, 4, 5],
[H | T] = Nums, % H = 1, T = [2,3,4,5]
io:format("~p~n", [H]). - List comprehension:
[X * 2 || X <- Nums, X > 2]→[6, 8, 10]. - Tuples:
Point = {3, 4}, access via pattern match:{X, Y} = Point.
% Common list operations
Doubled = lists:map(fun(X) -> X * 2 end, Nums),
Evens = lists:filter(fun(X) -> X rem 2 =:= 0 end, Nums),
Sum = lists:foldl(fun(X, Acc) -> X + Acc end, 0, Nums). 10. Strings & Binaries
- Strings in Erlang are lists of integers (character codes).
- Binaries (
<<"...">>) are more memory‑efficient for large text.
Str = "Hello",
Bin = <<"Hello">>,
io:format("~s~n", [Str]),
io:format("~s~n", [binary_to_list(Bin)]). Common operations:
Len = length("hello"), % 5
Upper = string:to_upper("hello"), % "HELLO"
Joined = string:join(["a","b","c"], ","), % "a,b,c" - Use the
stringmodule (Erlang 20+) for Unicode‑aware string handling.
11. User Input
io:format("Enter your name: "),
{ok, Name} = io:read(""),
io:format("Hello, ~p!~n", [Name]). io:get_line/1reads a full line as a string (including newline).io:read/1parses an Erlang term from stdin.
12. Pattern Matching & Guards
Pattern matching is central to Erlang — it replaces most conditionals:
{ok, Value} = get_value(). % crash if not {ok, _}
[H | _] = some_list(). % bind head, ignore tail Guards add boolean constraints to patterns:
classify(X) when X > 0 -> positive;
classify(0) -> zero;
classify(X) when X < 0 -> negative. - Guards allow only a safe subset of expressions (no side effects).
- Multiple guards in one clause:
when X > 0, X < 100(both must hold).
13. Functions & Modules
Declaration
-module(math_utils).
-export([add/2, square/1]). Definition
add(A, B) -> A + B.
square(X) -> X * X. - Functions are identified by
Name/Arity(e.g.,add/2). - Multiple clauses are matched top‑to‑bottom.
Scope
| Scope | Notes |
|---|---|
| Module‑private | Not listed in -export — invisible outside module. |
| Exported | Listed in -export — callable as Module:Fun(Args). |
14. Fun Expressions
Anonymous functions (like function pointers or lambdas):
Double = fun(X) -> X * 2 end,
Result = Double(5), % 10
Apply = fun(F, X) -> F(X) end,
Apply(Double, 7). % 14 - Pass funs as arguments for callbacks and higher‑order functions.
- Reference named functions with
fun Module:Name/Arity.
Sorted = lists:sort(fun(A, B) -> A =< B end, [3,1,2]). 15. Concurrency Primitives
Pid = spawn(fun() -> io:format("Hi~n") end),
Pid ! {self(), hello},
receive
{From, Msg} ->
io:format("Got ~p from ~p~n", [Msg, From])
after 1000 ->
io:format("Timeout~n")
end. spawn/1orspawn/3creates a new lightweight process.!sends a message;receiveblocks until a matching message arrives.after Timeoutclause handles the no‑message case.link/1andmonitor/2for fault tolerance between processes.
16. Records
Records are named tuples — Erlang's equivalent of structs:
-record(person, {name, age = 0}).
P = #person{name = "Alice", age = 30},
io:format("~s is ~p~n", [P#person.name, P#person.age]). - Defined with
-record(Name, Fields)in module or header file. - Access fields with
Record#record_name.field. - Update:
P2 = P#person{age = 31}(creates a new record).
17. Error Handling
try
risky_operation()
catch
throw:Reason -> io:format("Thrown: ~p~n", [Reason]);
error:Reason -> io:format("Error: ~p~n", [Reason]);
exit:Reason -> io:format("Exit: ~p~n", [Reason])
after
cleanup()
end. error:badarg,error:badarith, etc. are standard runtime errors.erlang:error(Reason)raises an error;throw(Reason)for flow control.
| Technique | Description |
|---|---|
Pattern match {ok, V} / {error, R} | Idiomatic error propagation. |
try/catch | Exception handling. |
catch Expr | Returns {'EXIT', Reason} on error. |
dbg / redbug | Tracing and debugging. |
18. File I/O
| Mode | Symbol |
|---|---|
read | Open for reading. |
write | Open for writing (truncate). |
append | Open for appending. |
binary | Read/write raw binaries. |
{ok, File} = file:open("data.txt", [read]),
{ok, Line} = file:read_line(File),
io:format("~s", [Line]),
file:close(File). file:read_file(Path)reads entire file into a binary in one call.file:write_file(Path, Data)writes and closes in one call.
19. OTP Basics
OTP (Open Telecom Platform) provides battle‑tested behaviours:
- gen_server — generic server process.
- supervisor — manages child processes and restart strategies.
- application — defines application lifecycle.
Example skeleton of a gen_server:
-behaviour(gen_server).
-export([start_link/0, init/1, handle_call/3, handle_cast/2]).
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
init([]) -> {ok, #{}}.
handle_call(_Msg, _From, State) ->
{reply, ok, State}.
handle_cast(_Msg, State) ->
{noreply, State}. 20. Core Standard Modules
| Module | Key Functions | Example |
|---|---|---|
io | format/2, get_line/1 | io:format("~s", ["Hello"]) |
lists | map/2, filter/2, foldl/3 | lists:map(fun(X) -> X*2 end, [1,2,3]) |
maps | put/3, get/2, merge/2 | maps:get(a, #{a=>1}) |
string | to_upper/1, join/2, split/2 | string:to_upper("hi") |
file | read_file/1, write_file/2 | file:read_file("f.txt") |
timer | sleep/1, send_after/3 | timer:sleep(1000) |
ets | new/2, insert/2, lookup/2 | ets:new(tab, [named_table]) |
21. Hot Code Swapping
code:load_file(my_module). - Allows updating a running module without stopping the VM.
- Running processes continue on the old version until they call into the module again.
- OTP behaviours handle version transitions via
code_change/3callbacks.
22. Miscellaneous
- Macros (
-define(NAME, Value).) for constants:?MODULE,?LINE. - Include files:
-include("records.hrl").to share record definitions. - Ports: interface to external C programs or OS processes.
- NIFs (Native Implemented Functions): embed C code directly in Erlang.
- Distribution:
net_kernel:start/1to connect BEAM nodes across machines.
23. Quick Reference Cheat Sheet
% Module declaration
-module(foo).
-export([bar/1]).
% Record definition
-record(point, {x = 0, y = 0}).
% Function with pattern matching
bar(0) -> zero;
bar(N) when N > 0 -> positive;
bar(_) -> negative.
% List comprehension
Squares = [X*X || X <- lists:seq(1, 5)].
% Spawn a process and message it
Pid = spawn(fun() ->
receive
{From, Msg} -> From ! {self(), Msg}
end
end),
Pid ! {self(), hello},
receive Reply -> io:format("~p~n", [Reply]) end.
% Error handling
try risky() catch error:R -> io:format("Error: ~p~n", [R]) end. Final Note
This guide is intentionally terse. For deeper explanations, examples, and exercises, refer to the official Erlang/OTP documentation or books like Programming Erlang by Joe Armstrong. Happy coding!