Skip to content

Dict[S @ {...}]

Dictionaries are ordered, mutable key-value mappings. They preserve insertion order and are multi-maps: a single key can have multiple values.

Keys can be any hashable type.

Ordering

Dictionaries preserve insertion order. Iteration yields entries in the order they were inserted.

Multi-Map Semantics

A dict can store multiple values per key. This is primarily relevant when constructing dicts from spreading or using methods with the instance parameter:

  • Construction with duplicate keys preserves all values
  • Plain indexing (d[key]) returns the last value for a key, so a duplicate key overrides the values before it: last wins
  • Plain assignment (d[key] = value) replaces all values for a key
  • insert adds a new value without removing existing ones for that key
  • get and pop accept an instance parameter to access specific values by their position (0-indexed) among values for that key; negative instance indexes count from the end

Inherits from: Iterable[Tuple[Value, Value]]

Implements: Index[S], Assign[S], Spread[S], Unpack[S]

Constructor

Dict source

Builds a dictionary from one spreadable source of key-value pairs. The lowercase dict factory instead assigns integer keys to positional arguments and symbol keys to key arguments.

Methods

(index) index

let d = {name: "Alice"}
assert_eq $d[:name:] "Alice"
d[:age:] = 30

Missing keys raise an error on access. Assignment replaces all values for the key.

Range values are treated as ordinary keys, not as slices.

(iter)() -> Iter[Tuple[Value, Value]]

Iterating over a dictionary yields [key, value] pairs:

for pair = {a: 1, b: 2}
  echo $pair

(unpack)()

Destructures the dictionary by key.

let :name age: years = {name: "Alice", age: 30}

clear()

Removes all key-value pairs.

let d = {a: 1, b: 2}
d.clear()
assert_eq $d.len 0

contains key … -> Bool

Tests whether the dictionary contains the given key. If a value is provided, tests whether any value associated with that key matches the given value (multi-map aware).

Parameters

NameTypeDescription
key the key to check
value? optional value to check for (multi-map)

Example

let d = {a: 1, b: 2}
d.insert "multi" "first"
d.insert "multi" "second"

# Key-only check. A bareword key is a `Sym`, so `"a"` would not match it.
assert (d.contains :a:)
assert (!d.contains :z:)

# Key + value check (multi-map aware)
assert (d.contains "multi" "first")
assert (d.contains "multi" "second")
assert (!d.contains "multi" "third")
Open in playground

copy() -> Dict[S]

Returns a shallow copy of the dictionary.

Insertion order and multiple per-key values are preserved. Keys and values are not copied recursively.

When inherited by a Do subclass, copy() calls the subclass constructor with the source dict as a single positional argument.

count key? -> Int

Returns a count derived from the dictionary's multi-map structure.

With no key, it returns the number of distinct keys. With a key, it returns the number of values associated with that key.

Missing keys return 0.

delete key -> Bool

Indicates whether any values were removed. Removes all values for the key.

Parameters

NameTypeDescription
key the key to remove

Example

let d = {a: 1, b: 2}
assert (d.delete :a:)
assert (!(d.delete :missing:))
assert_eq $d.len 1

get[D = nil] key … -> (Value | D)

Retrieves the value for a key. Returns nil if the key is missing and no alternative is provided. Negative instance indexes count from the end.

Parameters

NameTypeDescription
key the key to look up
instance? Int which value to retrieve when a key has multiple values (0-indexed; negative counts from end; default: last)
:default? D
:else? (() -> D)

Example

let d = {name: "Alice"}
assert_eq (d.get :name:) "Alice"
assert_eq ({name: "Alice", name: "Bob"}.get :name: -1) "Bob"
assert_eq (d.get :missing: default: "unknown") "unknown"

insert key value

Adds a key-value pair. Does not remove existing values for the same key (multi-map insert).

Parameters

NameTypeDescription
key the key
value the value

keys() -> Iter[Value]

Returns an iterator of keys. Each distinct key is yielded exactly once, in the order its first pair was inserted.

If duplicate-key iteration is needed, use pairs instead.

len() -> Int

Returns the number of key-value pairs (counting each value in a multi-map separately).

pairs() -> Iter[Tuple[Value, Value]]

Returns an iterator yielding [key, value] pairs, the same as ordinary iteration. This method is present to allow uniform key/value iteration over both Dict and Array.

pop[D = Empty] key … -> (Value | D)

Removes and returns a value for a key. Raises an error if the key is missing and no alternative is provided. Supports instance for multi-map access to remove a specific value by its position among values for that key. Negative instance indexes count from the end.

Parameters

NameTypeDescription
key the key to remove
instance? Int which value to remove when a key has multiple values (0-indexed; negative counts from end; default: first)
:default? D
:else? (() -> D)

Example

let d = {a: 1, b: 2}
d.insert "multi" "first"
d.insert "multi" "second"

# Pop first instance (default)
assert_eq (d.pop "multi") "first"

# Pop specific instance
assert_eq (d.pop "multi" 0) "second"

values key? -> Iter[Value]

Returns an iterator of values. With no argument, it yields all stored values in pair insertion order. With a key, it yields only the values associated with that key, in that key's insertion order.

Missing keys return an empty iterator.