Tuples, Records & Maps

Records are tuples at runtime: {person, "Ann", 0, undefined}.

13.1 Records — named tuples (compile-time)

Records are tuples at runtime: {person, "Ann", 0, undefined}. Share definitions through .hrl header files:

In the shell: rr("person.hrl"). loads records; rd(person, {name, age}). defines one.

-record(person, {name, age = 0, email = undefined}).

new_person() -> #person{name = "Ann", age = 30}.

P = #person{name = "Ann"},
P#person.name,                        % "Ann" — field access
P2 = P#person{age = 31},              % update
#person{name = Name} = P,             % pattern match
is_record(P, person),                 % true (also usable in guards)
record_info(fields, person).          % [name,age,email]
%% person.hrl
-record(person, {name :: string(), age = 0 :: non_neg_integer()}).
%% in a module
-include("person.hrl").

13.2 Maps (OTP 17+)

Guards: is_map/1, is_map_key/2, map_get/2, map_size/1.

M = #{name => "Ann", age => 30},
#{name := Name} = M,                  % match: := for existing keys
M2 = M#{age := 31},                   % update existing key (crashes if absent)
M3 = M#{city => "Oslo"},              % insert or update
maps:get(name, M),                    % "Ann" (badkey error if missing)
maps:get(city, M, unknown),           % default value
maps:find(name, M),                   % {ok,"Ann"} | error
maps:put(k, v, M), maps:remove(age, M),
maps:is_key(name, M), map_size(M),
maps:keys(M), maps:values(M), maps:to_list(M), maps:from_list([{a, 1}]),
maps:merge(#{a => 1}, #{b => 2}),
maps:merge_with(fun(_K, V1, V2) -> V1 + V2 end, #{a => 1}, #{a => 2}),  % OTP 24+
maps:map(fun(_K, V) -> V * 2 end, #{a => 1}),
maps:filter(fun(_K, V) -> V > 1 end, #{a => 1, b => 2}),
maps:fold(fun(K, V, Acc) -> [{K, V} | Acc] end, [], M),
maps:update_with(count, fun(C) -> C + 1 end, 1, #{}),
maps:with([name], M), maps:without([age], M),
maps:groups_from_list(fun(X) -> X rem 2 end, [1, 2, 3]),   % OTP 25+
maps:iterator(M), maps:next(It).

13.3 Records vs maps

compile-time fields, fast need .hrl sharing typos caught at compile time flexible, JSON-like used heavily in OTP state preferred for new code / APIs