On this page:
Map
Map.of
Readable  Map
Mutable  Map
Map.by
Mutable  Map.by
#%braces
#%braces
Map
Map
Map.by
Map.by
#%braces
Map
Readable  Map
Map.by
Map
Map.by
Mutable  Map
Mutable  Map.by
Map.empty
Map.empty
Readable  Map.empty
Readable  Map.empty
Map.length
Map.append
Map.keys
Map.values
Map.get
Map.remove
Mutable  Map.set
Mutable  Map.delete
Map.has_  key
Map.copy
Map.snapshot
Map.to_  sequence
8.12

6.34 Maps🔗ℹ

A map associates a value with each of a set of keys. Immutable maps can be constructed using the syntax {key_expr: val_expr, ...}, which creates a map from the values of the key_exprs to the corresponding values of the val_exprs. Note that using , in place of : creates a set with separate values, instead of a key–value mapping. More precisely, a use of curly braces with no preceding expression is parsed as an implicit use of the #%braces form.

A map is indexable using [] after a map expression with an expression for the key within []. Mutable maps can be updated with a combination of [] and assignment operators such as := (but use ++ to functionally update an immutable map). These uses of square brackets are implemented by #%index. A map can be used as sequence, in which case it supplies a key and its associated value (as two result values) in an unspecified order.

The . operator can be used on a readbale map (immutable or mutable) expression as equivalent to calling Map functions:

mp.length()

 is 

Map.length(mp)

mp.keys(try_sort, ...)

 is 

Map.keys(mp, try_sort, ...)

mp.values()

 is 

Map.values(mp)

mp.get(k)

 is 

Map.get(mp, k)

mp.has_key(k)

 is 

Map.has_key(mp, k)

mp.copy()

 is 

Map.copy(mp)

mp.snapshot()

 is 

Map.snapshot(mp)

mp.to_sequence()

 is 

Map.to_sequence(mp)

The . operator can be used on a map (immutable only) expression as equivalent to calling Map functions:

mp.append(mp2, ...)

 is 

Map.append(mp, mp2, ...)

mp.remove(k)

 is 

Map.remove(mp, k)

The . operator can be used on a mutable map expression as equivalent to calling MutableMap functions:

mp.set(k, v)

 is 

MutableMap.set(mp, k, v)

mp.delete(k)

 is 

MutableMap.delete(mp, k)

annotation

Map

 

annotation

Map.of(key_annot, val_annot)

 

annotation

ReadableMap

 

annotation

MutableMap

 

annotation

Map.by(key_comp)

 

annotation

Map.by(key_comp).of(key_annot, val_annot)

 

annotation

MutableMap.by(key_comp)

The Map annotation matches any immutable map in the form without of. The of variants match an immutable map whose keys satisfy key_annot and whose values satisfy val_annot.

ReadableMap matches both mutable and immutable maps, while MutableMap matches mutable maps (created with, for example, the MutableMap constructor).

The Map.by and MutableMap.by annotation variants match only maps that use the hash and equality procedures specified by key_comp.

Static information associated by Map, etc., makes an expression acceptable as a sequence to for in static mode.

expression

#%braces {key_val_or_splice, ...}

 

key_val_or_splice

 = 

key_expr: val_expr

 | 

key_repet: val_repet , ellipses

 | 

& map_expr

 

expression

#%braces {expr_or_splice, ...}

 

expr_or_splice

 = 

elem_expr

 | 

elem_repet , ellipses

 | 

& set_expr

 

ellipses

 = 

ellipsis

 | 

ellipses , ellipsis

 

ellipsis

 = 

...

 

repetition

#%braces {key_repet_or_splice, ...}

 

repetition

#%braces {repet_or_splice, ...}

Constructs either an immutable map or immutable set, depending on whether key_expr and val_expr are provided or elem_expr is provided. If no elements are provided directly, the result is a map (not a set). Map/set constructions can also serve as repetitions, where key_repet_or_splice and repet_or_splice are like key_val_or_splice and expr_or_splice, but with repetitions in place of expressions.

When ... is used among the content with two repetitions (for a map) or one repetition (for a set), the paired key and value elements (for a map) or value elements (for a set) are included in the result map or set. When & map_expr or & set_expr appears among the content, the immutable map or immutable set produced by map_expr or set_expr is included in the result map or set.

Mappings or elements are added to the result map or set left-to-right, which means that a later key_expr or elem_expr may replace one earlier in the sequence. This ordering applies to mappings or elements spliced via ... and &, too.

The #%braces form is implicitly used when {} is used in in an expression or repetition position. See also Implicit Forms.

> {1, 2, 3}

{1, 2, 3}

> {"a": 1, "b": 2}

{"a": 1, "b": 2}

> #%braces {1, 2, 3}

{1, 2, 3}

> #%braces {"a": 1, "b": 2}

{"a": 1, "b": 2}

> {1, 2, & {3, 4}}

{1, 2, 3, 4}

> {"a": 1, "b": 2, & {"c": 3, "d": 4}}

{"a": 1, "b": 2, "c": 3, "d": 4}

expression

Map{key_val_or_splice, ...}

 

repetition

Map{key_repet_or_splice, ...}

 

key_val_or_splice

 = 

key_expr: val_expr

 | 

key_repet: val_repet , ellipsis

 | 

& map_expr

 

ellipsis

 = 

...

 

function

fun Map([key :: Any, val :: Any] :: Listable.to_list, ...)

  :: Map

 

expression

Map.by(key_comp){key_val_or_splice, ...}

 

expression

Map.by(key_comp)

 

repetition

Map.by(key_comp){key_repet_or_splice, ...}

Constructs an immutable map containing given keys mapped to the given values, equivalent to using {key_val_or_splice, ...} for the {} form, or {key: val, ...} for the function form. The {} form works as a repetition, where key_repet_or_splice is like key_val_or_splice with repetitions in place of expressions.

The Map.by variants create a map that uses the equality and hashing functions specified by key_comp for keys.

> def m = Map{"x": 1, "y": 2}

> m

{"x": 1, "y": 2}

> m["x"]

1

> Map(["x", 1], ["y", 2])

{"x": 1, "y": 2}

> Map{"a": 4, "b": 4, & m}

{"a": 4, "b": 4, "x": 1, "y": 2}

> Map.by(===){"x" +& "": 1, "" +& "x": 2}

Map.by(===){"x": 1, "x": 2}

binding operator

#%braces {key_expr: val_bind, ...}

 

binding operator

#%braces {key_expr: val_bind, ..., map_rest}

 

map_rest

 = 

& map_bind

 | 

rest_key_bind: rest_val_bind , ellipsis

 

binding operator

#%braces {expr, ...}

 

binding operator

#%braces {expr, ..., set_rest}

 

set_rest

 = 

& set_bind

 | 

rest_bind , ellipsis

 

ellipsis

 = 

...

Matches either an immutable map or immutable set, depending on whether key_expr and val_bind are provided or expr is provided. If no key_expr or expr are provided, the binding matches a map (not a set).

See Map and Set for more information.

The #%braces form is implicitly used when {} is used in in a binding position. See also Implicit Forms.

> def {"x": x, "y": y} = Map{"x": 1, "y": 2}

> y

2

> def {"b", z, ...} = Set{"a", "b", "c"}

> [z, ...]

["c", "a"]

binding operator

Map{key_expr: val_bind, ...}

 

binding operator

Map{key_expr: val_bind, ..., rest}

 

binding operator

Map([key_expr, val_bind], ...)

 

binding operator

ReadableMap{key_expr: val_bind, ...}

 

binding operator

ReadableMap{key_expr: val_bind, ..., rest}

 

binding operator

ReadableMap([key_expr, val_bind], ...)

 

binding operator

Map.by(key_comp){key_expr: val_bind, ...}

 

binding operator

Map.by(key_comp){key_expr: val_bind, ..., rest}

 

binding operator

Map.by(key_comp)([key_expr, val_bind], ...)

 

rest

 = 

& map_bind

 | 

rest_key_bind: rest_val_bind , ellipsis

 

ellipsis

 = 

...

Matches a map of the keys computed by key_expr to values that match the corresponding val_binds. The matched map may have additional keys and values. If & map_bind is supplied, the rest of the map excluding the given key_exprs must match the map_bind. Static information associated by Map is propagated to map_bind. If rest_key_bind: rest_val_bind followed by ... is supplied, the rest of the map excluding the given key_exprs must have individual keys that match rest_key_bind and values that match rest_val_bind, and identifiers in rest_key_bind and rest_val_bind are bound as repetitions. Values matching rest_key_bind and rest_val_bind are extracted eagerly and preserved in internal lists to implement the repetitions.

The Map binding forms match only immutable maps, while ReadableMap forms match both immutable and mutable maps. For ReadableMap, the & map_bind will match a snapshot (in the sense of Map.snapshot) of the rest of the map. The Map.by binding forms match only immutable maps constructed using key_comp.

> def Map{"x": x, "y": y} = {"x": 1, "y": 2}

> y

2

> def Map{"a": a} = {"a": 1, "b": 2, "c": 3}

> a

1

> def Map{"a": _, & rst} = {"a": 1, "b": 2, "c": 3}

> rst

{"b": 2, "c": 3}

> def Map{"a": _, key: val, ...} = {"a": 1, "b": 2, "c": 3}

> [key, ...]

["c", "b"]

> [val, ...]

[3, 2]

> match Map.by(===){}

  | Map.by(==){}: "by equal"

  | Map.by(===){}: "by object identity"

"by object identity"

reducer

Map

 

reducer

Map.by(key_comp)

A reducer used with for, expects two results from a for body, and accumulates them into a map using the first result as a key and the second result as a value.

The Map.by reducer creates a map that uses the equality and hashing functions specified by key_comp.

expression

MutableMap{key_expr: val_expr, ...}

 

function

fun MutableMap([key :: Any, val :: Any] :: Listable.to_list, ...)

  :: MutableMap

 

expression

MutableMap.by(key_comp){key_expr: val_expr, ...}

 

expression

MutableMap.by(key_comp)

Similar to Map as a constructor, but creates a mutable map that can be updated using and assignment operator lik :=.

Note that ... and & are not supported for constructing mutable maps, only immutable maps.

> def m = MutableMap{"x": 1, "y": 2}

> m

MutableMap{"x": 1, "y": 2}

> m["x"]

1

> m["x"] := 0

> m

MutableMap{"x": 0, "y": 2}

value

def Map.empty :: Map = {}

 

binding operator

Map.empty

 

value

def ReadableMap.empty :: ReadableMap = {}

 

binding operator

ReadableMap.empty

An empty map. The Map.empty binding form differs from from {} or Map(), because Map.empty matches only an empty immutable map, while {} or Map() matches any immutable map.

The ReadableMap.empty binding form matches an empty map whether it is mutable or immutable.

Corresponding to the binding forms, Map.empty and ReadableMap.empty are bound to {} with approapriate static information.

> Map.empty

{}

> match {}

  | Map.empty: "empty map"

  | _: #false

"empty map"

> match {"x": 1, "y": 2}

  | Map.empty: "empty map"

  | _: #false

#false

> match {"x": 1, "y": 2}

  | {}: "curly braces allow extra"

  | _: #false

"curly braces allow extra"

> match {"x": 1, "y": 2}

  | Map(): "Map binding allows extra"

  | _: #false

"Map binding allows extra"

> match MutableMap{}

  | Map.empty: "empty immutable map"

  | _: #false

#false

> match MutableMap{}

  | ReadableMap.empty: "empty map for now"

  | _: #false

"empty map for now"

function

fun Map.length(mp :: ReadableMap) :: Int

Returns the number of key–value mappings in mp.

> Map.length({"a": 1, "b": 2})

2

> Map.length({})

0

> {"a": 1, "b": 2}.length()

2

> {}.length()

0

function

fun Map.append(mp :: Map, ...) :: Map

Functionally appends mps, like the ++ operator (but without the special optimization). When a key has a value in multiple given mps, the rightmost value is used.

> {1: "a", 2: "b"}.append({1: "c"}, {1: "d"})

{1: "d", 2: "b"}

> {1: "a", 2: "b"} ++ {1: "c"} ++ {1: "d"}

{1: "d", 2: "b"}

function

fun Map.keys(mp :: ReadableMap,

             try_sort :: Any = #false)

  :: List

Returns the keys of mp in a list. If try_sort is true, then the elements are sorted to the degree that a built-in comparison can sort them.

> Map.keys({"a": 1, "b": 2}, #true)

["a", "b"]

function

fun Map.values(mp :: ReadableMap) :: List

Returns the values of mp in a list.

> Map.values({"a": 1, "b": 2})

[2, 1]

function

fun Map.get(mp :: ReadableMap,

            key :: Any,

            default :: Any:

              fun (): throw Exn.Fail.Contract(....))

  :: Any

Equivalent mp[key] (with the default implicit #%index form) when default is not provided, otherwise default is used when mp does not contain a mapping for key. In that case, if default is a function, then the function is called with zero arguments to get a result, otherwise default is returned as the result.

> Map.get({"a": 1, "b": 2}, "a")

1

> {"a": 1, "b": 2}["a"]

1

> Map.get({"a": 1, "b": 2}, "c", #inf)

#inf

> Map.get({"a": 1, "b": 2}, "c", fun (): error("no value"))

no value

function

fun Map.remove(mp :: Map, key :: Any) :: Map

Returns a map like mp, but without a mapping for key is mp has one.

> Map.remove({"a": 1, "b": 2}, "a")

{"b": 2}

> Map.remove({"a": 1, "b": 2}, "c")

{"a": 1, "b": 2}

function

fun MutableMap.set(mp :: MutableMap,

                   key :: Any, val :: Any)

  :: Void

Equivalent to mp[key] := val (with the default implicit #%index form). Changes mp to map key to val.

> def m = MutableMap{"a": 1, "b": 2}

> m.set("a", 3)

> m

MutableMap{"a": 3, "b": 2}

> m["a"] := 4

> m

MutableMap{"a": 4, "b": 2}

function

fun MutableMap.delete(mp :: MutableMap, key :: Any) :: Void

Changes mp to remove a mapping for key, if any.

> def m = MutableMap{"a": 1, "b": 2}

> m.delete("c")

> m

MutableMap{"a": 1, "b": 2}

> m.delete("a")

> m

MutableMap{"b": 2}

function

fun Map.has_key(mp :: ReadableMap, key :: Any) :: Boolean

Returns #true if key is mapped to a value in mp, #false otherwise.

> Map.has_key({"a": 1, "b": 2}, "a")

#true

> Map.has_key({"a": 1, "b": 2}, "c")

#false

Creates a mutable map whose initial content matches mp.

function

fun Map.snapshot(mp :: ReadableMap) :: Map

Returns an immutable map whose content matches mp. If mp is immutable, then it is the result.

Implements Sequenceable by returning a sequence of mp’s keys and values (as two result values) in an unspecified order.