Skip to content
Modules and Exports
step 1/7

Reading — step 1 of 7

Learn

~2 min readRecursion, Modules, and Maps

Erlang code is organized into modules. A module is a single .erl file with a -module/1 directive and -export/1 list. Programming Erlang treats modules as the unit of code organization.

Module file structure

%% File: math_utils.erl
-module(math_utils).
-export([double/1, square/1, sum/1]).

double(N) -> N * 2.
square(N) -> N * N.
sum(L) -> lists:sum(L).
  • -module(math_utils). must match the filename (math_utils.erl)
  • -export([fn/arity, ...]) — public functions; everything else is private
  • arity is the parameter count: double/1, sum/1

Calling functions

From another module:

math_utils:double(5)        %% 10
math_utils:square(7)         %% 49

The syntax is Module:Function(Args). From WITHIN the module, just double(5) works.

Multiple arities — same name, different signatures

-export([greet/0, greet/1]).

greet() -> greet("World").
greet(Name) -> io:format("Hello, ~s~n", [Name]).

greet/0 and greet/1 are DIFFERENT functions to Erlang. Common Erlang pattern: a 0/1-argument public version that delegates to a more general version.

Module attributes (metadata)

-module(my_mod).
-export([api/1]).
-vsn("1.0").
-behaviour(gen_server).      %% if implementing an OTP behavior

Attributes start with -. Some are processed by the compiler (-module, -export, -behaviour), others are user metadata.

Records and headers (.hrl)

For record definitions shared across modules, put them in a header file:

%% person.hrl
-record(person, {name, age, email}).

Then include in any module:

-module(my_mod).
-include("person.hrl").

ada() -> #person{name = "Ada", age = 36}.

Headers are textually substituted at compile time — like C #include.

Module-level constants

No const. Use -define:

-define(MAX_RETRIES, 5).
-define(PI, 3.14159).

area(R) -> ?PI * R * R.

The ?NAME syntax expands at compile time. Capitalized convention.

Hot code reload

A running Erlang VM can replace a module's code without restart — foundation of Erlang's famous nine-nines uptime. The BEAM keeps two versions of each loaded module so live updates work without dropping connections.

Common mistakes

  • Filename / module name mismatch — -module(foo). must be in foo.erl.
  • Forgetting to export a function — Module:fn(X) from outside fails with undef. Add the function/arity to -export.
  • Wrong arity in -export — -export([fn/2]) for a function defined as fn/3 won't link.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…