Erlang basics · Lesson 22 (open contents)
01 · Open erl02 · Meet common terms03 · Tell two kinds of text apart04 · Bind a variable once05 · Split and filter a list06 · Parse a number safely07 · Choose one path with case08 · Let a function keep going09 · Put code in a module10 · Compare terms and Boolean results11 · Read and update nested maps12 · Build and inspect UTF-8 binaries13 · Let clauses choose the function path14 · Solve a list twice15 · Choose with patterns, guards, and errors16 · Describe a module and one record17 · Put one tested module in Rebar318 · Return success or failure as data19 · Read and write one file safely20 · Build a data pipeline with functions21 · Keep records behind a module boundary22 · Define a module contract23 · Describe the data contract24 · Test small rules and whole flows25 · Shape builds and make a command26 · Write the project promise27 · Parse one real line28 · Keep the public API small29 · Make the promise executable30 · Package the edge and leave clues31 · Prove the project is done
ERLANG · INTERMEDIATE · LESSON 2225 minutes

Define a module contract

Declare a callback and implement it in a separate module.

01 · Start with the whole example

Run this first

Run it once, change one input, and compare the new result.

Erlang
%% greeter.erl declares the contract
-module(greeter).
-callback greet(binary()) -> binary().

%% friendly.erl implements it
-module(friendly).
-behaviour(greeter).
-export([greet/1]).
greet(Name) -> <<"Hello, ", Name/binary>>.
Check the result first
  • After compiling both modules, friendly:greet(<<"Maya">>) returns <<"Hello, Maya">>.
02 · Take the code apart

Read from the first line down

  1. Read -callback: Declare one required function signature.
  2. Read -behaviour(Module).: State which contract this module implements.
  3. Read -export([greet/1]).: Make the callback callable.
03 · Meet the new symbols

Symbols are not secret signs

-callback

Declare one required function signature.

-behaviour(Module).

State which contract this module implements.

-export([greet/1]).

Make the callback callable.

04 · Ideas inside the code

Match each name to its meaning

01

behaviour

A behaviour lists callback functions that implementing modules promise to export.

02

callback

A callback specification names the arguments and return type required by the contract.

03

implementation

The behaviour attribute asks the compiler to warn when callbacks are missing.

05 · Make the idea clear

Why these forms are useful

Run the example first. Predict one result, then change one input and run it again.

A behaviour lists callback functions that implementing modules promise to export.

A callback specification names the arguments and return type required by the contract.

DESIGN DECISION

Why this shape?

Why does a behaviour define callbacks without creating a process?

Choice

A behaviour first states which functions a module must implement. GenServer/gen_server is a behaviour with a runtime protocol, but a general behaviour starts nothing by itself.

Cost and boundary

It standardizes a boundary. It does not choose state ownership, supervision, capacity, or error policy for you.

A FAMILIAR POINT OF VIEW

Coming from Java, Python, or JavaScript

Java

Familiar starting point
An interface defines a method contract.
What BEAM changes
A behaviour constrains module/function/arity entries, which callers still invoke as module functions.
False friend
Implementing one creates neither an object nor a thread.

Python

Familiar starting point
An ABC or Protocol.
What BEAM changes
Callback metadata helps tools check an implementation and lets OTP invoke it.
False friend
It is not a decorator that wraps runtime calls.

JavaScript

Familiar starting point
A conventional object shape or TypeScript interface.
What BEAM changes
A behaviour lives at the BEAM module and callback-entry level.
False friend
A type contract and a process lifecycle remain separate decisions.
06 · Change it yourself

Close the answer and try

Add the behaviour attribute to another module.

Practice starting point
-module(formal).
____
-export([greet/1]).

Target result: Declare greeter as the behaviour.

Stuck? Read one hint

Use the -behaviour(...) attribute.

After you run it, see one answer
One answer
-module(formal).
-behaviour(greeter).
-export([greet/1]).
Think about it: Does a behaviour start a process?

No. It is a module contract. OTP behaviours add process patterns in later lessons.

Take with you

Remember these three lines

  1. 1

    Behaviours declare contracts.

  2. 2

    Callbacks need exported implementations.

  3. 3

    A generic behaviour does not imply concurrency.

Lesson completeRun the code once, then mark this lesson as done.