Reading — step 1 of 7
Learn
Erlang's map (added in OTP 17, 2014) is the modern dictionary type. The Erlang docs treat it as the standard key-value structure for new code.
Creating maps
M = #{name => "Ada", age => 36, email => "[email protected]"}.
#{ }is the map literalK => Vfor each entry- Any term can be a key; any term can be a value
Accessing values
maps:get(name, M) %% "Ada" — throws if missing
maps:get(missing, M, default) %% "default" — with fallback
maps:find(name, M) %% {ok, "Ada"}
maps:find(missing, M) %% error
#{Key := Value} syntax for pattern matching:
#{name := Name} = M,
io:format("~s~n", [Name]). %% "Ada"
The := is the EXACT MATCH (key must exist). => is for assignment.
Updating maps
M2 = M#{age => 37}. %% new map with age changed
M3 = M#{role => admin}. %% new map with role added
M4 = maps:remove(email, M). %% new map without email
Maps are immutable — every "update" returns a new map.
#{key := value} for must-exist update:
M5 = M#{age := 38}. %% requires age key to exist; errors otherwise
Distinguish ADDING from MODIFYING — => adds or replaces, := only modifies existing.
Iterating
maps:fold(fun(K, V, Acc) -> [{K, V} | Acc] end, [], M).
maps:keys(M). %% [name, age, email]
maps:values(M). %% ["Ada", 36, "[email protected]"]
maps:size(M). %% 3
maps:to_list/1 and maps:from_list/1 convert between maps and key-value lists.
Pattern matching on maps
process(#{type := user, name := Name}) ->
{user, Name};
process(#{type := admin, perms := P}) ->
{admin, P};
process(_) ->
unknown.
The pattern only matches if all listed keys are present with matching values. Useful for shape-based dispatch.
Maps vs records vs proplists
Erlang has THREE key-value structures:
| Map | Record | Proplist | |
|---|---|---|---|
| Keys | Any term | Atoms (compile-time) | Atoms (usually) |
| Type-checked at compile | No | Yes | No |
| Performance | O(log n) lookup | O(1) field access | O(n) lookup |
| Best for | Variable-shape data | Fixed structs | Function options |
Modern Erlang code prefers maps for most data. Records remain common for fixed-shape internal data; proplists are legacy.
Common mistakes
- Confusing
=>and:=—=>adds or updates;:=requires the key to exist. Different semantics. - Using maps where records fit better — for fixed-shape internal data with known fields, records are faster and type-checked.
- Pattern matching on absent keys — pattern fails silently. Use maps:find/2 for explicit handling.
- Forgetting maps are unordered — don't depend on iteration order between operations.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…