tur/map
typed Map[K V]: persistent hash map requiring Hash[K] and MapKey[K].
Since: Phase TM0 (typed surface: Phase TMS2)
Map
(defstruct Map [K V])
parameterized persistent map with key type K and value type V.
Since: Phase TM0
map-new
(map-new [K V])
create a new empty typed map.
An empty Map[K V].
(:: (map-new) (Map int int)) ; => empty Map[int int]
Since: Phase TM0
map-empty-for
(map-empty-for [^Hash K ^MapKey K V])
internal: an empty Map[K V] whose K/V are pinned by a
Since: Phase TMS3
map-hamt
(map-hamt [K V])
internal accessor for the HAMT backing store.
map-wrap
(map-wrap [K V])
internal constructor from a HAMT pointer.
map-assoc-eq-o
(map-assoc-eq-o [K V])
============================================================================
map-get-eq-o
(map-get-eq-o [K V])
raw lookup: explicit hash, boxed carrier key, comparator.
map-has-eq-o?
(map-has-eq-o? [K V])
raw existence test: explicit hash, boxed carrier key.
map-dissoc-eq-o
(map-dissoc-eq-o [K V])
raw removal: explicit hash, boxed carrier key, comparator.
map-assoc-eq
(map-assoc-eq [K V])
----------------------------------------------------------------------------
| m | source Map[K V] | |
| h | precomputed content hash of key | |
| key | key of type K | |
| val | value of type V | |
| keyeq | a captureless (c-fn [K K] bool) used to compare keys that share a | |
| hash. Must carry no environment (it is called as a bare C function | ||
| pointer); pass a top-level defn or a captureless lambda, or a | ||
| MapKey carrier comparator like tur-int-carrier-eq? / | ||
| tur-cstr-key-eq?. A capturing closure is rejected at compile time. |
A new Map[K V] with the entry inserted or updated. Keys that are equal under keyeq (not just identical pointers) collapse to one entry.
(map-assoc-eq m (cstr-hash k) k v tur-cstr-key-eq?)
Since: TCE4
map-get-eq
(map-get-eq [K V])
look up a key using an explicit hash and key-equality fn.
| m | Map[K V] | |
| h | precomputed content hash of key | |
| key | key of type K | |
| keyeq | key comparison fn (see map-assoc-eq) |
The value of type V, or 0 (none) if absent.
(map-get-eq m (cstr-hash k) k tur-cstr-key-eq?)
Since: TCE4
map-has-eq?
(map-has-eq? [K V])
key-existence test using an explicit hash and equality fn.
| m | Map[K V] | |
| h | precomputed content hash of key | |
| key | key of type K | |
| keyeq | key comparison fn (see map-assoc-eq) |
true if the key is present under keyeq, false otherwise.
(map-has-eq? m (cstr-hash k) k tur-cstr-key-eq?) ; => true or false
Since: TCE4
map-dissoc-eq
(map-dissoc-eq [K V])
remove a key using an explicit hash and equality fn.
| m | source Map[K V] | |
| h | precomputed content hash of key | |
| key | key of type K | |
| keyeq | key comparison fn (see map-assoc-eq) |
A new Map[K V] with the key removed.
(map-dissoc-eq m (cstr-hash k) k tur-cstr-key-eq?)
Since: TCE4
cstr-hash
(cstr-hash [s : cstr] :)
xxHash64 of a NUL-terminated string's contents.
| s | the string to hash |
The 64-bit content hash, so equal text hashes equally regardless of pointer identity.
(cstr-hash "key") ; => <stable content hash>
Since: TCE4
tur-cstr-key-eq?
(tur-cstr-key-eq? [a : cstr b : cstr] :)
internal: content equality of two string keys.
tur-int-carrier-eq?
(tur-int-carrier-eq? [a : int b : int] :)
============================================================================
tur-f32-carrier-eq?
(tur-f32-carrier-eq? [a : int b : int] :)
carrier comparator for :float32 keys.
tur-f64-carrier-eq?
(tur-f64-carrier-eq? [a : int b : int] :)
carrier comparator for :float (float64) keys.
MapKey[int]
(definstance MapKey [int])
one-word identity carrier; integer-equality comparator.
MapKey[bool]
(definstance MapKey [bool])
one-word 0/1 carrier; integer-equality comparator.
MapKey[cstr]
(definstance MapKey [cstr])
pointer carrier; content-equality comparator.
MapKey[float32]
(definstance MapKey [float32])
bit-reinterpret carrier; float-value comparator.
MapKey[float]
(definstance MapKey [float])
bit-reinterpret carrier (float64); double-value comparator.
tur-map-kcheck
(tur-map-kcheck [K V])
============================================================================
map-assoc
(map-assoc [m k v])
insert or update a key/value pair; returns a new map.
| m | source Map[K V] | |
| key | key of type K (must satisfy Hash[K] and MapKey[K]). | |
| Inline float keys (:float32 / :float) are bit-reinterpreted into | ||
| the carrier and compared by value; cstr keys are compared by | ||
| content; one-word keys are unchanged. | ||
| val | value of type V (any type: scalar, float, or a heap handle) |
A new Map[K V] with the entry inserted or updated. Keys equal under Eq[K] (not just identical) collapse to one entry.
(map-assoc (:: (map-new) (Map cstr int)) "name" 1) ; => Map {"name" -> 1}
(map-assoc (:: (map-new) (Map int int)) 42 100) ; => Map {42 -> 100}
Since: Phase TMS3 (macro accessor; was map-assoc-g; GHE3)
map-get
(map-get [m k])
look up a key; returns the value or 0 (none) if absent.
| m | Map[K V] | |
| key | key of type K (must satisfy Hash[K] and MapKey[K]) |
The value of type V, or 0 (none) if absent. For a non-int value type read the result with an ascription, e.g. (:: (map-get m k) :float).
(map-get m "name") ; => value or 0
Since: Phase TMS3 (macro accessor; was map-get-g; GHE3)
map-has?
(map-has? [m k])
check whether a key exists in the map.
| m | Map[K V] | |
| key | key of type K (must satisfy Hash[K] and MapKey[K]) |
true if the key is present under Eq[K], false otherwise.
(map-has? m "name") ; => true or false
Since: Phase TMS3 (macro accessor; was map-has-g?; GHE3)
map-dissoc
(map-dissoc [m k])
remove a key from the map; returns a new map.
| m | source Map[K V] | |
| key | key of type K (must satisfy Hash[K] and MapKey[K]) |
A new Map[K V] with the key removed.
(map-dissoc m "name") ; => map without "name"
Since: Phase TMS3 (macro accessor; was map-dissoc-g; GHE3)
map-count
(map-count [K V])
return the number of entries in the map.
| m | Map[K V] |
Integer count of key/value pairs.
(map-count my-map) ; => 3
Since: Phase TM0
map-merge
(map-merge [K V])
merge two maps; values from b win on key collision.
| a | first Map[K V] | |
| b | second Map[K V] (wins on collision) |
A new Map[K V] containing all entries from both maps.
(map-merge map-a map-b) ; => merged map
Since: Phase TM0
map-free
(map-free [K V])
free the Map wrapper (does not free HAMT; use map-free-all for that).
| m | Map[K V] to free |
(map-free my-map)
Since: Phase TM0
map-eq-raw?
(map-eq-raw? [m1 : int m2 : int ^fat val-cmp])
compare two maps for structural equality using a value comparator.
| m1 | first Map[K V] | |
| m2 | second Map[K V] | |
| val-cmp | comparator fn [a :int b :int] :bool applied to each value pair |
true if both maps have identical keys and all corresponding values satisfy val-cmp.
(map-eq? ma mb (fn [a b] (= a b))) ; => true
Since: Phase TM0
map-eq?
(map-eq? [K V])
typed structural equality over Map[K V] (delegates to map-eq-raw?).
| m1 | first Map[K V] | |
| m2 | second Map[K V] | |
| val-cmp | comparator fn [a :int b :int] :bool applied to each value pair |
true if both maps have identical keys and all corresponding values satisfy val-cmp.
Since: Phase TM0 (typed surface: TMS3)
map-eq-raw-k?
(map-eq-raw-k? [m1 : int m2 : int keyeq ^fat val-cmp])
like map-eq-raw? but compares keys with an explicit
map-eq-k?
(map-eq-k? [K V])
structural equality over Map[K V] with an explicit key
map-eq-dynamic
(map-eq-dynamic [m1 : int m2 : int ^fat val-cmp] :)
structural equality using the value type's Eq instance.
map-iter-cur-val-as
(map-iter-cur-val-as [V])
typed read of an iter box's current value.
map-get-dynamic-as
(map-get-dynamic-as [V])
typed lookup against m2's hamt, threading m1's
map-eq-loop
(map-eq-loop [K V])
pure-Turmeric structural-equality walk over m1's HAMT.
| iter | hamt/iter-alloc-allocated handle scanning m1 | |
| m2-hamt | raw HAMT pointer of the second map (from map-hamt) | |
| keyeq | stamped key comparator (from hamt/keyeq on m1's hamt) | |
| val-cmp | value comparator fn [a :V b :V] :bool |
true iff every entry of m1 is present in m2 under keyeq with an equal value under val-cmp.
Since: Phase TCO-Eq-MapSet
map-eq-driver
(map-eq-driver [K V])
allocate the iter box, run map-eq-loop, free.
Since: Phase TCO-Eq-MapSet
Eq[Map]
(definstance Eq [Map])
hamt-assoc-each__
(hamt-assoc-each__ [m & kvs])
internal helper for the hamt-of macro.
tur-map-homog__
(tur-map-homog__ [A])
internal: compile-time homogeneity check (see vec.tur).
hamt-homog-chain__
(hamt-homog-chain__ [& kvs])
internal: enforce homogeneous keys and values.
hamt-of
(hamt-of [& kvs])
variadic Map literal: alternating key/value arguments.
| & kvs -- an even number of arguments, alternating key then value. | ||
| Keys may be any Hash/MapKey scalar type K (:int, :cstr, :bool, | ||
| :float32, :float); all keys must unify to a single K and all | ||
| values to a single V, else TUR-E0001 on the offending element. | ||
| String keys are compared by content; int/bool by value; float | ||
| keys round-trip by value. |
A fresh Map[K V] populated with the given entries; later duplicate keys win. map-get returns the value type V, so a non-int value is read with an ascription, e.g. (:: (map-get m k) :cstr). Note: this is the lowering target of the #map{...} data literal (-Xdata-literals). Writing #map{:a 1 :b 2} is preferred over calling hamt-of directly. A non-empty literal is seeded from a value-pinned empty (map-empty-for) so the key/value types flow from the first pair; an empty (hamt-of) yields a bare (map-new) that must be annotated by the surrounding context.
(hamt-of) ; => empty Map (annotate at the binding site)
(hamt-of 1 10 2 20) ; => Map {1 -> 10, 2 -> 20}
(hamt-of "a" 1 "b" 2) ; => Map {"a" -> 1, "b" -> 2}, content-keyed
Since: DL1 (data-literals-plan); typed surface: TMS3