Deep merge block b2 on top of b1, merges nested blocks but not lists
block?
True if and only if v is a block
list?
True if and only if v is a list
elements
Expose list of elements of block b
block
(re)construct block from list kvs of elements
has(s, b)
True if and only if block b has key (symbol) s
lookup(s, b)
Look up symbol s in block b, error if not found
lookup-in(b, s)
Look up symbol s in block b, error if not found
lookup-or(s, d, b)
Look up symbol s in block b, default d if not found
lookup-or-in(b, s, d)
Look up symbol s in block b, default d if not found
b ~ :k
Safe key lookup — returns value at key :k if b is a block containing :k, else null. Null-propagating: returns null for non-block and null inputs. Left-associative, precedence 90.
lookup-alts(syms, d, b)
Look up symbols syms in turn in block b until a value is found, default d if none
lookup-across(s, d, bs)
Look up symbol s in turn in each of blocks bs until a value is found, default d if none
Queries using dot-separated patterns with wildcards:
Bare name foo is sugar for **.foo (find at any depth)
* matches one level
** matches any depth
data: {
us: { config: { host: "us.example.com" } }
eu: { config: { host: "eu.example.com" } }
}
# Find all hosts under any config
hosts: data deep-query("config.host") # ["us.example.com", "eu.example.com"]
# Wildcard: any key at one level, then host
hosts: data deep-query("*.config.host")
The pb: namespace provides persistent (immutable, structurally-shared) blocks backed by
im::OrdMap. These offer O(log n) lookup and merge operations with structural sharing.
This feature is experimental and is not included in generated documentation exports.
Function
Description
pb.from-block(b)
Convert a standard block b into a persistent block
pb.lookup(k, d, p)
Look up key (symbol) k in persistent block p, returning default d if absent
pb.to-list(p)
Return an ordered list of [key, value] pairs from persistent block p
pb.merge(l, r)
Merge persistent blocks l and r; left-hand values win on key conflicts
pb.merge-with(f, l, r)
Merge persistent blocks l and r, resolving conflicts with f(left-val, right-val)
# Round-trip a standard block through a persistent block
p: {a: 1, b: 2} pb.from-block
v: p pb.lookup(:a, 0) # 1
l: p pb.to-list block # {a: 1, b: 2}
# Merge two persistent blocks (left wins on conflict)
merged: ({a: 1} pb.from-block) pb.merge({a: 99, b: 2} pb.from-block)
# pb.lookup(:a, 0) merged => 1