Associative Lists / Dictionaries: Difference between revisions
(Created page with "= Associative Lists / Dictionaries = The '''Associative Lists / Dictionaries''' module provides key-value data structure operations for the SCM programming language. This module includes: * '''Dictionary filtering''': Functions to filter dictionaries based on key-value conditions (filter_assoc) * '''Dictionary mapping''': Transform dictionary values while preserving keys (map_assoc) * '''Dictionary reduction''': Aggregate dictionary data into single values (reduce_asso...") |
Wikiservice (talk | contribs) (Refresh MemCP documentation: accuracy, operational guidance, performance profile and maintained API reference) |
||
| (One intermediate revision by one other user not shown) | |||
| Line 1: | Line 1: | ||
<!-- Copyright (C) 2026 Carl-Philip Haensch --> | |||
<!-- SPDX-License-Identifier: GPL-3.0-or-later --> | |||
<span id="associative-lists--dictionaries"></span> | |||
= Associative Lists / Dictionaries = | = Associative Lists / Dictionaries = | ||
<!-- Generated from MemCP c42e19eba on 2026-08-27; do not edit manually. --> | |||
<div class="mw-message-box mw-message-box-notice">Generated from MemCP commit <code>c42e19eba</code> on 27 August 2026. See [[Full SCM API documentation]].</div> | |||
The '''Associative Lists / Dictionaries''' module works with functional key/value collections. It includes: | |||
* lookup and presence checks; | |||
* extraction, filtering, and mapping by key and value; | |||
* immutable updates and merges; | |||
* reductions and sorting; | |||
* structural indexes and catalogs for repeated lookups. | |||
Ordinary operations return a new value instead of mutating an outer binding. This makes associative data safe to share through functional query code; use explicit sessions or synchronization primitives when mutable shared state is required. | |||
== filter_assoc == | == filter_assoc == | ||
| Line 19: | Line 24: | ||
'''Allowed number of parameters:''' 2–2 | '''Allowed number of parameters:''' 2–2 | ||
<span id="parameters"></span> | |||
=== Parameters === | |||
* '''dict''' (<code>list</code>): dictionary that has to be filtered | * '''dict''' (<code>list</code>): dictionary that has to be filtered | ||
* '''condition''' (<code>func</code>): | * '''condition''' (<code>func</code>): returns whether a dictionary entry should be included | ||
** '''Parameters''' | |||
*** '''key''' (<code>string</code>): entry key | |||
*** '''value''' (<code>any</code>): entry value | |||
** '''Returns''' | |||
*** '''included''' (<code>bool</code>): whether to include the entry | |||
<span id="returns"></span> | |||
=== Returns === | |||
* '''value''' (<code>list</code>) | |||
== find_assoc == | |||
returns the first key/value pair that passes the condition function, or nil/default if none matches | |||
'''Allowed number of parameters:''' 2–3 | |||
<span id="parameters-1"></span> | |||
=== Parameters === | |||
* '''dict''' (<code>list</code>): dictionary to search | |||
* '''condition''' (<code>func</code>): predicate applied until the first matching dictionary entry | |||
** '''Parameters''' | |||
*** '''key''' (<code>string</code>): entry key | |||
*** '''value''' (<code>any</code>): entry value | |||
** '''Returns''' | |||
*** '''matches''' (<code>bool</code>): whether the entry matches | |||
* '''default''' (<code>any</code>): optional default value if nothing matches ''(optional)'' | |||
<span id="returns-1"></span> | |||
=== Returns === | |||
''' | * '''value''' (<code>any</code>) | ||
== map_assoc == | == map_assoc == | ||
returns a mapped dictionary according to a map function | returns a mapped dictionary according to a map function Keys will stay the same but values are mapped. | ||
'''Allowed number of parameters:''' 2–2 | '''Allowed number of parameters:''' 2–2 | ||
<span id="parameters-2"></span> | |||
=== Parameters === | |||
* '''dict''' (<code>list</code>): dictionary that has to be mapped | * '''dict''' (<code>list</code>): dictionary that has to be mapped | ||
* '''map''' (<code>func</code>): | * '''map''' (<code>func</code>): transforms each dictionary value | ||
** '''Parameters''' | |||
*** '''key''' (<code>string</code>): entry key | |||
*** '''value''' (<code>any</code>): entry value | |||
** '''Returns''' | |||
*** '''mapped_value''' (<code>any</code>): replacement value | |||
''' | <span id="returns-2"></span> | ||
=== Returns === | |||
* '''value''' (<code>list</code>) | |||
== reduce_assoc == | == reduce_assoc == | ||
| Line 43: | Line 91: | ||
'''Allowed number of parameters:''' 3–3 | '''Allowed number of parameters:''' 3–3 | ||
<span id="parameters-3"></span> | |||
=== Parameters === | |||
* '''dict''' (<code>list</code>): dictionary that has to be reduced | * '''dict''' (<code>list</code>): dictionary that has to be reduced | ||
* '''reduce''' (<code>func</code>): | * '''reduce''' (<code>func</code>): combines the accumulator with each dictionary entry | ||
** '''Parameters''' | |||
*** '''acc''' (<code>any</code>): current accumulator | |||
*** '''key''' (<code>string</code>): entry key | |||
*** '''value''' (<code>any</code>): entry value | |||
** '''Returns''' | |||
*** '''acc''' (<code>any</code>): next accumulator | |||
* '''neutral''' (<code>any</code>): initial value for the accumulator | * '''neutral''' (<code>any</code>): initial value for the accumulator | ||
''' | <span id="returns-3"></span> | ||
=== Returns === | |||
* '''value''' (<code>any</code>) | |||
== make_structural_index == | |||
Builds an immutable structural-expression index. It eagerly hashes every key and every node under roots, then returns a parallel-safe lookup function that maps an equal expression to its zero-based key position or nil. | |||
'''Allowed number of parameters:''' 2–2 | |||
<span id="parameters-4"></span> | |||
=== Parameters === | |||
* '''keys''' (<code>list</code>): immutable structural expressions to index | |||
* '''roots''' (<code>list</code>): immutable expression roots whose descendant hashes are precomputed | |||
<span id="returns-4"></span> | |||
=== Returns === | |||
* '''lookup''' (<code>func</code>): looks up the indexed position of a structurally equal expression | |||
** '''Parameters''' | |||
*** '''expression''' (<code>any</code>): a key, root, descendant of a declared root, or scalar expression | |||
** '''Returns''' | |||
*** '''position''' (<code>int|nil</code>): zero-based key position, or nil when the expression is not indexed | |||
== make_structural_catalog == | |||
Creates an atomic compile-local structural catalog. Look up with (catalog key), insert with (catalog key value), or freeze with (catalog) for parallel-safe read-only lookup. | |||
'''Allowed number of parameters:''' 0–1 | |||
<span id="parameters-5"></span> | |||
=== Parameters === | |||
* '''mode''' (<code>bool|symbol</code>): true forces collisions for tests; ast selects type-stable compiler equality ''(optional)'' | |||
<span id="returns-5"></span> | |||
=== Returns === | |||
* '''catalog''' (<code>func</code>): atomic structural-expression lookup and update function | |||
** '''Parameters''' | |||
*** '''key''' (<code>any</code>): expression to look up; omit to freeze the catalog ''(optional)'' | |||
*** '''value''' (<code>any</code>): value to store for key ''(optional)'' | |||
** '''Returns''' | |||
*** '''result''' (<code>any|func</code>): stored value, lookup result, or frozen lookup function | |||
**** '''Parameters''' | |||
***** '''key''' (<code>any</code>): expression to look up in the frozen catalog | |||
**** '''Returns''' | |||
***** '''value''' (<code>any</code>): value stored for a structurally equal expression, or nil | |||
<span id="has_assoc"></span> | |||
== has_assoc? == | == has_assoc? == | ||
| Line 56: | Line 162: | ||
'''Allowed number of parameters:''' 2–2 | '''Allowed number of parameters:''' 2–2 | ||
<span id="parameters-6"></span> | |||
=== Parameters === | |||
* '''dict''' (<code>list</code>): dictionary that has to be checked | * '''dict''' (<code>list</code>): dictionary that has to be checked | ||
* '''key''' (<code>string</code>): key to test | * '''key''' (<code>string</code>): key to test | ||
'''Returns:''' <code> | <span id="returns-6"></span> | ||
=== Returns === | |||
* '''value''' (<code>bool</code>) | |||
== get_assoc == | |||
gets a value from a dictionary by key, returns nil if not found | |||
'''Allowed number of parameters:''' 2–3 | |||
<span id="parameters-7"></span> | |||
=== Parameters === | |||
* '''dict''' (<code>list</code>): dictionary to look up | |||
* '''key''' (<code>any</code>): key to look up | |||
* '''default''' (<code>any</code>): optional default value if key not found ''(optional)'' | |||
<span id="returns-7"></span> | |||
=== Returns === | |||
* '''value''' (<code>any</code>) | |||
== get_assoc_pairlist == | |||
gets a value from a list of key/value rows without flattening the rows | |||
'''Allowed number of parameters:''' 3–3 | |||
<span id="parameters-8"></span> | |||
=== Parameters === | |||
* '''rows''' (<code>list</code>): list whose rows contain a key followed by one or more values | |||
* '''key''' (<code>any</code>): key compared with the first item of each row | |||
* '''default''' (<code>any</code>): value returned when no row contains the key | |||
<span id="returns-8"></span> | |||
=== Returns === | |||
* '''value''' (<code>any</code>) | |||
== extract_assoc == | == extract_assoc == | ||
| Line 68: | Line 215: | ||
'''Allowed number of parameters:''' 2–2 | '''Allowed number of parameters:''' 2–2 | ||
<span id="parameters-9"></span> | |||
=== Parameters === | |||
* '''dict''' (<code>list</code>): dictionary that has to be checked | * '''dict''' (<code>list</code>): dictionary that has to be checked | ||
* '''map''' (<code>func</code>): | * '''map''' (<code>func</code>): extracts one element per dictionary entry | ||
** '''Parameters''' | |||
*** '''key''' (<code>string</code>): entry key | |||
*** '''value''' (<code>any</code>): entry value | |||
** '''Returns''' | |||
*** '''element''' (<code>any</code>): element extracted from the entry | |||
<span id="returns-9"></span> | |||
=== Returns === | |||
''' | * '''value''' (<code>list</code>) | ||
== set_assoc == | == set_assoc == | ||
returns a dictionary where a single value has been changed. | returns a new dictionary where a single value has been changed. The original dictionary is not modified. | ||
'''Allowed number of parameters:''' 3–4 | '''Allowed number of parameters:''' 3–4 | ||
<span id="parameters-10"></span> | |||
* '''dict''' (<code>list</code>): input dictionary | === Parameters === | ||
* '''dict''' (<code>list</code>): input dictionary | |||
* '''key''' (<code>string</code>): key that has to be set | * '''key''' (<code>string</code>): key that has to be set | ||
* '''value''' (<code>any</code>): new value to set | * '''value''' (<code>any</code>): new value to set | ||
* '''merge''' (<code>func</code>): (optional) | * '''merge''' (<code>func</code>): combines values when an existing entry is overwritten ''(optional)'' | ||
** '''Parameters''' | |||
*** '''old''' (<code>any</code>): existing value | |||
*** '''new''' (<code>any</code>): replacement value | |||
** '''Returns''' | |||
*** '''merged''' (<code>any</code>): value stored in the new dictionary | |||
''' | <span id="returns-10"></span> | ||
=== Returns === | |||
* '''value''' (<code>list</code>) | |||
== merge_assoc == | == merge_assoc == | ||
| Line 94: | Line 261: | ||
'''Allowed number of parameters:''' 2–3 | '''Allowed number of parameters:''' 2–3 | ||
<span id="parameters-11"></span> | |||
=== Parameters === | |||
* '''dict1''' (<code>list</code>): first input dictionary that has to be changed. You must not use this value again. | * '''dict1''' (<code>list</code>): first input dictionary that has to be changed. You must not use this value again. | ||
* '''dict2''' (<code>list</code>): input dictionary that contains the new values that have to be added | * '''dict2''' (<code>list</code>): input dictionary that contains the new values that have to be added | ||
* '''merge''' (<code>func</code>): (optional) | * '''merge''' (<code>func</code>): combines values when both dictionaries contain an entry ''(optional)'' | ||
** '''Parameters''' | |||
*** '''old''' (<code>any</code>): value from the first dictionary | |||
*** '''new''' (<code>any</code>): value from the second dictionary | |||
** '''Returns''' | |||
*** '''merged''' (<code>any</code>): value stored in the merged dictionary | |||
<span id="returns-11"></span> | |||
=== Returns === | |||
* '''value''' (<code>list</code>) | |||
== sort == | |||
returns a sorted copy of a list using a comparator (lambda (a b) truthy/falsy) | |||
'''Allowed number of parameters:''' 2–2 | |||
<span id="parameters-12"></span> | |||
=== Parameters === | |||
* '''list''' (<code>list</code>) | |||
* '''comparator''' (<code>func</code>) | |||
** '''Parameters''' | |||
*** '''parameter''' (<code>any</code>) | |||
*** '''parameter''' (<code>any</code>) | |||
** '''Returns''' | |||
*** '''value''' (<code>bool</code>) | |||
<span id="returns-12"></span> | |||
=== Returns === | |||
* '''value''' (<code>list</code>) | |||
== sort_mut == | |||
sorts a list in-place using a comparator (lambda (a b) truthy/falsy) | |||
'''Allowed number of parameters:''' 2–2 | |||
<span id="parameters-13"></span> | |||
=== Parameters === | |||
* '''list''' (<code>list</code>) | |||
* '''comparator''' (<code>func</code>) | |||
** '''Parameters''' | |||
*** '''parameter''' (<code>any</code>) | |||
*** '''parameter''' (<code>any</code>) | |||
** '''Returns''' | |||
*** '''value''' (<code>bool</code>) | |||
<span id="returns-13"></span> | |||
=== Returns === | |||
* '''value''' (<code>list</code>) | |||
== mapkey_assoc == | |||
returns a mapped dictionary according to a map function Values stay the same but keys are mapped. | |||
'''Allowed number of parameters:''' 2–2 | |||
<span id="parameters-14"></span> | |||
=== Parameters === | |||
* '''dict''' (<code>list</code>): dictionary whose keys have to be mapped | |||
* '''map''' (<code>func</code>): computes a replacement key for each dictionary entry | |||
** '''Parameters''' | |||
*** '''key''' (<code>string</code>): existing key | |||
*** '''value''' (<code>any</code>): entry value | |||
** '''Returns''' | |||
*** '''new_key''' (<code>any</code>): replacement key | |||
<span id="returns-14"></span> | |||
=== Returns === | |||
''' | * '''value''' (<code>list</code>) | ||
Latest revision as of 11:59, 28 August 2026
Associative Lists / Dictionaries
The Associative Lists / Dictionaries module works with functional key/value collections. It includes:
- lookup and presence checks;
- extraction, filtering, and mapping by key and value;
- immutable updates and merges;
- reductions and sorting;
- structural indexes and catalogs for repeated lookups.
Ordinary operations return a new value instead of mutating an outer binding. This makes associative data safe to share through functional query code; use explicit sessions or synchronization primitives when mutable shared state is required.
filter_assoc
returns a filtered dictionary according to a filter function
Allowed number of parameters: 2–2
Parameters
- dict (
list): dictionary that has to be filtered - condition (
func): returns whether a dictionary entry should be included- Parameters
- key (
string): entry key - value (
any): entry value
- key (
- Returns
- included (
bool): whether to include the entry
- included (
- Parameters
Returns
- value (
list)
find_assoc
returns the first key/value pair that passes the condition function, or nil/default if none matches
Allowed number of parameters: 2–3
Parameters
- dict (
list): dictionary to search - condition (
func): predicate applied until the first matching dictionary entry- Parameters
- key (
string): entry key - value (
any): entry value
- key (
- Returns
- matches (
bool): whether the entry matches
- matches (
- Parameters
- default (
any): optional default value if nothing matches (optional)
Returns
- value (
any)
map_assoc
returns a mapped dictionary according to a map function Keys will stay the same but values are mapped.
Allowed number of parameters: 2–2
Parameters
- dict (
list): dictionary that has to be mapped - map (
func): transforms each dictionary value- Parameters
- key (
string): entry key - value (
any): entry value
- key (
- Returns
- mapped_value (
any): replacement value
- mapped_value (
- Parameters
Returns
- value (
list)
reduce_assoc
reduces a dictionary according to a reduce function
Allowed number of parameters: 3–3
Parameters
- dict (
list): dictionary that has to be reduced - reduce (
func): combines the accumulator with each dictionary entry- Parameters
- acc (
any): current accumulator - key (
string): entry key - value (
any): entry value
- acc (
- Returns
- acc (
any): next accumulator
- acc (
- Parameters
- neutral (
any): initial value for the accumulator
Returns
- value (
any)
make_structural_index
Builds an immutable structural-expression index. It eagerly hashes every key and every node under roots, then returns a parallel-safe lookup function that maps an equal expression to its zero-based key position or nil.
Allowed number of parameters: 2–2
Parameters
- keys (
list): immutable structural expressions to index - roots (
list): immutable expression roots whose descendant hashes are precomputed
Returns
- lookup (
func): looks up the indexed position of a structurally equal expression- Parameters
- expression (
any): a key, root, descendant of a declared root, or scalar expression
- expression (
- Returns
- position (
int|nil): zero-based key position, or nil when the expression is not indexed
- position (
- Parameters
make_structural_catalog
Creates an atomic compile-local structural catalog. Look up with (catalog key), insert with (catalog key value), or freeze with (catalog) for parallel-safe read-only lookup.
Allowed number of parameters: 0–1
Parameters
- mode (
bool|symbol): true forces collisions for tests; ast selects type-stable compiler equality (optional)
Returns
- catalog (
func): atomic structural-expression lookup and update function- Parameters
- key (
any): expression to look up; omit to freeze the catalog (optional) - value (
any): value to store for key (optional)
- key (
- Returns
- result (
any|func): stored value, lookup result, or frozen lookup function- Parameters
- key (
any): expression to look up in the frozen catalog
- key (
- Returns
- value (
any): value stored for a structurally equal expression, or nil
- value (
- Parameters
- result (
- Parameters
has_assoc?
checks if a dictionary has a key present
Allowed number of parameters: 2–2
Parameters
- dict (
list): dictionary that has to be checked - key (
string): key to test
Returns
- value (
bool)
get_assoc
gets a value from a dictionary by key, returns nil if not found
Allowed number of parameters: 2–3
Parameters
- dict (
list): dictionary to look up - key (
any): key to look up - default (
any): optional default value if key not found (optional)
Returns
- value (
any)
get_assoc_pairlist
gets a value from a list of key/value rows without flattening the rows
Allowed number of parameters: 3–3
Parameters
- rows (
list): list whose rows contain a key followed by one or more values - key (
any): key compared with the first item of each row - default (
any): value returned when no row contains the key
Returns
- value (
any)
extract_assoc
applies a function (key value) on the dictionary and returns the results as a flat list
Allowed number of parameters: 2–2
Parameters
- dict (
list): dictionary that has to be checked - map (
func): extracts one element per dictionary entry- Parameters
- key (
string): entry key - value (
any): entry value
- key (
- Returns
- element (
any): element extracted from the entry
- element (
- Parameters
Returns
- value (
list)
set_assoc
returns a new dictionary where a single value has been changed. The original dictionary is not modified.
Allowed number of parameters: 3–4
Parameters
- dict (
list): input dictionary - key (
string): key that has to be set - value (
any): new value to set - merge (
func): combines values when an existing entry is overwritten (optional)- Parameters
- old (
any): existing value - new (
any): replacement value
- old (
- Returns
- merged (
any): value stored in the new dictionary
- merged (
- Parameters
Returns
- value (
list)
merge_assoc
returns a dictionary where all keys from dict1 and all keys from dict2 are present. If a key is present in both inputs, the second one will be dominant so the first value will be overwritten unless you provide a merge function
Allowed number of parameters: 2–3
Parameters
- dict1 (
list): first input dictionary that has to be changed. You must not use this value again. - dict2 (
list): input dictionary that contains the new values that have to be added - merge (
func): combines values when both dictionaries contain an entry (optional)- Parameters
- old (
any): value from the first dictionary - new (
any): value from the second dictionary
- old (
- Returns
- merged (
any): value stored in the merged dictionary
- merged (
- Parameters
Returns
- value (
list)
sort
returns a sorted copy of a list using a comparator (lambda (a b) truthy/falsy)
Allowed number of parameters: 2–2
Parameters
- list (
list) - comparator (
func)- Parameters
- parameter (
any) - parameter (
any)
- parameter (
- Returns
- value (
bool)
- value (
- Parameters
Returns
- value (
list)
sort_mut
sorts a list in-place using a comparator (lambda (a b) truthy/falsy)
Allowed number of parameters: 2–2
Parameters
- list (
list) - comparator (
func)- Parameters
- parameter (
any) - parameter (
any)
- parameter (
- Returns
- value (
bool)
- value (
- Parameters
Returns
- value (
list)
mapkey_assoc
returns a mapped dictionary according to a map function Values stay the same but keys are mapped.
Allowed number of parameters: 2–2
Parameters
- dict (
list): dictionary whose keys have to be mapped - map (
func): computes a replacement key for each dictionary entry- Parameters
- key (
string): existing key - value (
any): entry value
- key (
- Returns
- new_key (
any): replacement key
- new_key (
- Parameters
Returns
- value (
list)