User's Guide
PDF
Top

Erlang Reference Manual
User's Guide
Version 6.0

Expand All
Contract All

Chapters

- Introduction
  - Top of chapter
  - Purpose
  - Prerequisites
  - Document Conventions
  - Complete List of BIFs
  - Reserved Words
- Character Set and Source File Encoding
  - Top of chapter
  - Character Set
  - Source File Encoding
- Data Types
  - Top of chapter
  - Terms
  - Number
  - Atom
  - Bit Strings and Binaries
  - Reference
  - Fun
  - Port Identifier
  - Pid
  - Tuple
  - Map
  - List
  - String
  - Record
  - Boolean
  - Escape Sequences
  - Type Conversions
- Pattern Matching
  - Top of chapter
  - Pattern Matching
- Modules
  - Top of chapter
  - Module Syntax
  - Module Attributes
  - Comments
  - The module_info/0 and module_info/1 functions
- Functions
  - Top of chapter
  - Function Declaration Syntax
  - Function Evaluation
  - Tail recursion
  - Built-In Functions, BIFs
- Types and Function Specifications
  - Top of chapter
  - The Erlang Type Language
  - Types and their Syntax
  - Type declarations of user-defined types
  - Type information in record declarations
  - Specifications for functions
- Expressions
  - Top of chapter
  - Expression Evaluation
  - Terms
  - Variables
  - Patterns
  - Match
  - Function Calls
  - If
  - Case
  - Send
  - Receive
  - Term Comparisons
  - Arithmetic Expressions
  - Boolean Expressions
  - Short-Circuit Expressions
  - List Operations
  - Bit Syntax Expressions
  - Fun Expressions
  - Catch and Throw
  - Try
  - Parenthesized Expressions
  - Block Expressions
  - List Comprehensions
  - Bit String Comprehensions
  - Guard Sequences
  - Operator Precedence
- The Preprocessor
  - Top of chapter
  - File Inclusion
  - Defining and Using Macros
  - Predefined Macros
  - Macros Overloading
  - Flow Control in Macros
  - Stringifying Macro Arguments
- Maps
  - Top of chapter
  - Creating Maps
  - Updating Maps
  - Maps in Patterns
  - Maps in Guards
- Records
  - Top of chapter
  - Defining Records
  - Creating Records
  - Accessing Record Fields
  - Updating Records
  - Records in Guards
  - Records in Patterns
  - Nested records
  - Internal Representation of Records
- Errors and Error Handling
  - Top of chapter
  - Terminology
  - Exceptions
  - Handling of Run-Time Errors in Erlang
  - Exit Reasons
- Processes
  - Top of chapter
  - Processes
  - Process Creation
  - Registered Processes
  - Process Termination
  - Message Sending
  - Links
  - Error Handling
  - Monitors
  - Process Dictionary
- Distributed Erlang
  - Top of chapter
  - Distributed Erlang System
  - Nodes
  - Node Connections
  - epmd
  - Hidden Nodes
  - C Nodes
  - Security
  - Distribution BIFs
  - Distribution Command Line Flags
  - Distribution Modules
- Compilation and Code Loading
  - Top of chapter
  - Compilation
  - Code Loading
  - Code Replacement
  - Running a function when a module is loaded
- Ports and Port Drivers
  - Top of chapter
  - Ports
  - Port Drivers
  - Port BIFs

# 10 Maps

Note

Maps are considered experimental during OTP 17 and may be subject to change.

The documentation below describes it being possible to use arbitrary expressions or variables as keys, this is NOT implemented in the current version of Erlang/OTP.

Exceptions returns badarg instead of badmap, this will change in the future releases.

### 10.1 Creating Maps

Constructing a new map is done by letting an expression K be associated with another expression V:

    #{ K => V }

New maps may include multiple associations at construction by listing every association:

    #{ K1 => V1, .., Kn => Vn }

An empty map is constructed by not associating any terms with each other:

    #{}

All keys and values in the map are terms. Any expression is first evaluated and then the resulting terms are used as key and value respectively.

Keys and values are separated by the => arrow and associations are separated by ,.

Examples:

    M0 = #{},                 % empty map
    M1 = #{a => <<"hello">>}, % single association with literals
    M2 = #{1 => 2, b => b},   % multiple associations with literals
    M3 = #{k => {A,B}},       % single association with variables
    M4 = #{{"w", 1} => f()}.  % compound key associated with an evaluated expression

where, A and B are any expressions and M0 through M4 are the resulting map terms.

If two matching keys are declared, the latter key will take precedence.

Example:

    1> #{1 => a, 1 => b}.
    #{1 => b }
    2> #{1.0 => a, 1 => b}.
    #{1 => b, 1.0 => a}

The order in which the expressions constructing the keys and their associated values are evaluated is not defined. The syntactic order of the key-value pairs in the construction is of no relevance, except in the above mentioned case of two matching keys.

### 10.2 Updating Maps

Updating a map has similar syntax as constructing it.

An expression defining the map to be updated is put in front of the expression defining the keys to be updated and their respective values.

    M#{ K => V }

where M is a term of type map and K and V are any expression.

If key K does not match any existing key in the map, a new association will be created from key K to value V. If key K matches an existing key in map M its associated value will be replaced by the new value V. In both cases the evaluated map expression will return a new map.

If M is not of type map an exception of type badmap is thrown.

To only update an existing value, the following syntax is used,

    M#{ K := V }

where M is an term of type map, V is an expression and K is an expression which evaluates to an existing key in M.

If key K does not match any existing keys in map M an exception of type badarg will be triggered at runtime. If a matching key K is present in map M its associated value will be replaced by the new value V and the evaluated map expression returns a new map.

If M is not of type map an exception of type badmap is thrown.

Examples:

    M0 = #{},
    M1 = M0#{a => 0},
    M2 = M1#{a => 1, b => 2},
    M3 = M2#{"function" => fun() -> f() end},
    M4 = M3#{a := 2, b := 3}.  % 'a' and 'b' was added in `M1` and `M2`.

where M0 is any map. It follows that M1 .. M4 are maps as well.

More Examples:

    1> M = #{1 => a}.
    #{1 => a }
    2> M#{1.0 => b}.
    #{1 => a, 1.0 => b}.
    3> M#{1 := b}.
    #{1 => b}
    4> M#{1.0 := b}.
    ** exception error: bad argument

As in construction, the order in which the key and value expressions are evaluated is not defined. The syntactic order of the key-value pairs in the update is of no relevance, except in the case where two keys match, in which case the latter value is used.

### 10.3 Maps in Patterns

Matching of key-value associations from maps is done in the following way:

    #{ K := V } = M

where M is any map. The key K has to be an expression with bound variables or a literals, and V can be any pattern with either bound or unbound variables.

If the variable V is unbound, it will be bound to the value associated with the key K, which has to exist in the map M. If the variable V is bound, it has to match the value associated with K in M.

Example:

    1> M = #{"tuple" => {1,2}}.
    #{"tuple" => {1,2}}
    2> #{"tuple" := {1,B}} = M.
    #{"tuple" => {1,2}}
    3> B.
    2.

This will bind variable B to integer 2.

Similarly, multiple values from the map may be matched:

    #{ K1 := V1, .., Kn := Vn } = M

where keys K1 .. Kn are any expressions with literals or bound variables. If all keys exist in map M all variables in V1 .. Vn will be matched to the associated values of their respective keys.

If the matching conditions are not met, the match will fail, either with

- a badmatch exception, if used in the context of the matching operator as in the example,
- or resulting in the next clause being tested in function heads and case expressions.

Matching in maps only allows for := as delimiters of associations. The order in which keys are declared in matching has no relevance.

Duplicate keys are allowed in matching and will match each pattern associated to the keys.

    #{ K := V1, K := V2 } = M

Matching an expression against an empty map literal will match its type but no variables will be bound:

    #{} = Expr

This expression will match if the expression Expr is of type map, otherwise it will fail with an exception badmatch.

#### Matching syntax: Example with literals in function heads

Matching of literals as keys are allowed in function heads.

    %% only start if not_started
    handle_call(start, From, #{ state := not_started } = S) ->
    ...
        {reply, ok, S#{ state := start }};

    %% only change if started
    handle_call(change, From, #{ state := start } = S) ->
    ...
        {reply, ok, S#{ state := changed }};

### 10.4 Maps in Guards

Maps are allowed in guards as long as all sub-expressions are valid guard expressions.

Two guard BIFs handles maps:

- is_map/1
- map_size/1