# `nupp.util`
Small types that belong to no larger facility.
```nupp
local record Damage
amount: integer
end
const set = new nupp.util.Bitset(128)
set:set(7)
const damage = nupp.util.newPool(Damage, 64)
damage:release(damage:acquire())
const store = nupp.util.newStore()
const theme: nupp.util.Key = nupp.util.newKey("app.theme")
store:set(theme, "dark")
print(nupp.util.uuid4())
```
Each member is one type and the few functions that hand it out, reached by the
type's name rather than by a module of its own. [`Bitset`](#nupp.util.Bitset) is a set of bit
positions, [`Store`](#nupp.util.Store) is a bag of values indexed by typed [`Key`](#nupp.util.Key)s, and [`Pool`](#nupp.util.Pool)
leases cleared record instances from a free list. [`uuid4`](#nupp.util.uuid4) and [`uuid7`](#nupp.util.uuid7)
generate identifiers, and [`fnv1a64`](#nupp.util.fnv1a64) hashes bytes. [`try`](#nupp.util.try) and [`tryWith`](#nupp.util.tryWith) run
a function protected and answer `(result, reason)`, which is the layout the
`or return` suffix reads and `pcall`'s own is not.
Unlike `nupp.mem`, which keeps every member a module of its own, these are
re-exported here. Checked source still selects members independently, so using a
bitset does not retain UUID support. [`uuid4`](#nupp.util.uuid4) and [`uuid7`](#nupp.util.uuid7) are the only
members that resolve a host provider.
## Types
### `Bitset` _record_
```nupp
record Bitset ...
```
A growable set of bit positions counting from 0.
#### Members
| Name | Kind | Description |
| --- | --- | --- |
| [`words`](#nupp.util.Bitset.words) | field | Zero-based words, lowest bit first. |
| [`capacity`](#nupp.util.Bitset.capacity) | field | Words allocated. |
| [`used`](#nupp.util.Bitset.used) | field | An upper bound on the words that may hold a set bit: every word at or above it is zero. |
| [`population`](#nupp.util.Bitset.population) | field | The last resolved population, meaningful only when stale is false. |
| [`stale`](#nupp.util.Bitset.stale) | field | Whether population needs recomputing. |
| [`constructor`](#nupp.util.Bitset.constructor) | constructor | Creates an empty set. |
| [`reserve`](#nupp.util.Bitset.reserve) | method | Grows storage so at least bits bits fit. |
| [`set`](#nupp.util.Bitset.set) | method | Adds a bit, growing when it is past the end. |
| [`clear`](#nupp.util.Bitset.clear) | method | Removes a bit. |
| [`get`](#nupp.util.Bitset.get) | method | Whether a bit is set. |
| [`setRange`](#nupp.util.Bitset.setRange) | method | Adds every bit in the inclusive range, one word-mask write per word rather than one operation per bit. |
| [`count`](#nupp.util.Bitset.count) | method | How many bits are set. |
| [`isEmpty`](#nupp.util.Bitset.isEmpty) | method | Whether nothing is set. |
| [`clearAll`](#nupp.util.Bitset.clearAll) | method | Removes every bit, keeping capacity so a set reused each frame stops allocating once it has reached its peak. |
| [`setOnly`](#nupp.util.Bitset.setOnly) | method | Removes every bit, then adds exactly one. |
| [`wordCount`](#nupp.util.Bitset.wordCount) | method | An upper bound on the words that may hold a set bit. |
| [`wordAt`](#nupp.util.Bitset.wordAt) | method | One stored word. |
| [`nextSetBit`](#nupp.util.Bitset.nextSetBit) | method | The lowest set position at or after from. |
| [`positionsInto`](#nupp.util.Bitset.positionsInto) | method | Writes every set position at or after from into target, lowest first. |
| [`containsAll`](#nupp.util.Bitset.containsAll) | method | Whether every bit set in other is also set here. |
| [`overlaps`](#nupp.util.Bitset.overlaps) | method | Whether at least one bit is set in both. |
| [`disjoint`](#nupp.util.Bitset.disjoint) | method | Whether the two share no set bit. |
| [`copyFrom`](#nupp.util.Bitset.copyFrom) | method | Replaces these bits with a copy of other's. |
| [`orWith`](#nupp.util.Bitset.orWith) | method | Adds every bit set in other. |
| [`andWith`](#nupp.util.Bitset.andWith) | method | Keeps only the bits also set in other. |
| [`andNotWith`](#nupp.util.Bitset.andNotWith) | method | Removes every bit set in other. |
| [`xorWith`](#nupp.util.Bitset.xorWith) | method | Keeps only the bits set in exactly one of the two. |
#### `words` _field_
```nupp
words: uint32[?]
```
`@private`
Zero-based words, lowest bit first. Every word from `used` up to
`capacity` is zero, which is the invariant every word loop relies on.
#### `capacity` _field_
```nupp
capacity: integer
```
`@private`
Words allocated.
#### `used` _field_
```nupp
used: integer
```
`@private`
An upper bound on the words that may hold a set bit: every word at or
above it is zero. Deliberately not the exact high-water mark, because
keeping that exact costs a backwards scan on every clear and every
intersection.
#### `population` _field_
```nupp
population: integer
```
`@private`
The last resolved population, meaningful only when `stale` is false.
#### `stale` _field_
```nupp
stale: boolean
```
`@private`
Whether `population` needs recomputing. Set algebra marks it rather than
paying two popcounts per word to keep a number most callers never read.
#### `constructor` _constructor_
```nupp
constructor: function constructor(self, capacityBits: integer?)
```
Creates an empty set.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | the set being initialized |
| `capacityBits` | `integer?` | how many bits to allocate initially; setting a later position grows the set |
##### Raises
| Type | Condition |
| --- | --- |
| `string` | when capacityBits is more than 2^31 |
#### `reserve` _method_
```nupp
reserve: function reserve(self, bits: integer): nil
```
Grows storage so at least `bits` bits fit. Only grows, and never returns
storage. A growth at least doubles, so repeated small growths stay
amortised.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `bits` | `integer` | how many bits must fit |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
##### Raises
| Type | Condition |
| --- | --- |
| `string` | when bits is NaN or more than 2^31 |
#### `set` _method_
```nupp
set: function set(self, index: integer): nil
```
Adds a bit, growing when it is past the end.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `index` | `integer` | the bit position, counting from 0 |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
##### Raises
| Type | Condition |
| --- | --- |
| `string` | when index is negative, past 2^31 - 1, or not an integer |
#### `clear` _method_
```nupp
clear: function clear(self, index: integer): nil
```
Removes a bit. Never allocates, and never narrows the used-word bound,
so it stays constant-time whichever bit it was.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `index` | `integer` | the bit position, counting from 0. One past the end, a negative one included, does nothing. |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### `get` _method_
```nupp
get: function get(self, index: integer): boolean
```
Whether a bit is set.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `index` | `integer` | the bit position, counting from 0 |
##### Returns
| Type | Description |
| --- | --- |
| `boolean` | false for any position past the end, so no bound check is needed at the call site |
#### `setRange` _method_
```nupp
setRange: function setRange(self, low: integer, high: integer): nil
```
Adds every bit in the inclusive range, one word-mask write per word
rather than one operation per bit.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `low` | `integer` | the first position added, counting from 0 |
| `high` | `integer` | the last position added. Below `low` adds nothing, so an empty range needs no guard at the call site. |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
##### Raises
| Type | Condition |
| --- | --- |
| `string` | when low is negative, when high is past 2^31 - 1, or when either is not an integer |
#### `count` _method_
```nupp
count: function count(self): integer
```
How many bits are set. Resolves a pending recount, so a caller that
reads it every frame pays for the set algebra it skipped; one that never
reads it never pays.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
##### Returns
| Type | Description |
| --- | --- |
| `integer` | the number of set bits |
#### `isEmpty` _method_
```nupp
isEmpty: function isEmpty(self): boolean
```
Whether nothing is set. Says nothing about capacity.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
##### Returns
| Type | Description |
| --- | --- |
| `boolean` | true when no bit is set |
#### `clearAll` _method_
```nupp
clearAll: function clearAll(self): nil
```
Removes every bit, keeping capacity so a set reused each frame stops
allocating once it has reached its peak.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### `setOnly` _method_
```nupp
setOnly: function setOnly(self, index: integer): nil
```
Removes every bit, then adds exactly one.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `index` | `integer` | the one position left set, counting from 0 |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
##### Raises
| Type | Condition |
| --- | --- |
| `string` | when index is negative, past 2^31 - 1, or not an integer; the set is left unchanged |
#### `wordCount` _method_
```nupp
wordCount: function wordCount(self): integer
```
An upper bound on the words that may hold a set bit. Every word at or
above it is zero, and it is not narrowed by `clear` or by intersection,
so it may exceed the exact high-water mark.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
##### Returns
| Type | Description |
| --- | --- |
| `integer` | the number of words a word-at-a-time walk must visit |
#### `wordAt` _method_
```nupp
wordAt: function wordAt(self, index: integer): integer
```
One stored word. Word `w` holds positions `w * WORD_BITS` through
`w * WORD_BITS + WORD_BITS - 1`, lowest position first.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `index` | `integer` | a word index counting from 0, bounded by `wordCount` |
##### Returns
| Type | Description |
| --- | --- |
| `integer` | the word as a signed value, so one with its top bit set reads negative, and 0 for any index outside the bound |
#### `nextSetBit` _method_
```nupp
nextSetBit: function nextSetBit(self, from: integer): integer
```
The lowest set position at or after `from`.
Stateless, so nested walks do not interfere and a mutation between calls
cannot invalidate a walk in progress.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `from` | `integer` | the lowest position that may be returned, counting from 0 |
##### Returns
| Type | Description |
| --- | --- |
| `integer` | that position, or -1 when there is none |
#### `positionsInto` _method_
```nupp
positionsInto: function positionsInto(self, target: int32[?], capacity: integer, from: integer): integer, integer
```
Writes every set position at or after `from` into `target`, lowest first.
One call rather than one per position. A walk pays a call and a word read
for every position it returns, which for a few thousand positions is most
of what it costs; this reads each word once and clears the position it
just reported out of a register.
`target` is a pointer and a count because that is what a native kernel
takes. Filling it here rather than allocating keeps a per-frame extraction
allocation-free, and leaves the boundary where a native one would sit.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `target` | `int32\[?\]` | where positions are written, indexed from 0 |
| `capacity` | `integer` | how many positions `target` holds |
| `from` | `integer` | the lowest position that may be written, counting from 0 |
##### Returns
| Type | Description |
| --- | --- |
| `integer` | how many positions were written, and the position to resume from when `target` filled first, or -1 when the set is exhausted |
| `integer` | |
##### Raises
| Type | Condition |
| --- | --- |
| `string` | when capacity is negative |
#### `containsAll` _method_
```nupp
containsAll: function containsAll(self, other: Bitset): boolean
```
Whether every bit set in `other` is also set here.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `other` | `Bitset` | read and not modified |
##### Returns
| Type | Description |
| --- | --- |
| `boolean` | true when `other` is a subset. An empty `other` is contained by anything. |
#### `overlaps` _method_
```nupp
overlaps: function overlaps(self, other: Bitset): boolean
```
Whether at least one bit is set in both. Early-exiting, and deliberately
not an intersection followed by a count.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `other` | `Bitset` | read and not modified, as is the receiver |
##### Returns
| Type | Description |
| --- | --- |
| `boolean` | true when the two share a set bit |
#### `disjoint` _method_
```nupp
disjoint: function disjoint(self, other: Bitset): boolean
```
Whether the two share no set bit.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `other` | `Bitset` | read and not modified, as is the receiver |
##### Returns
| Type | Description |
| --- | --- |
| `boolean` | the negation of `overlaps` |
#### `copyFrom` _method_
```nupp
copyFrom: function copyFrom(self, other: Bitset): nil
```
Replaces these bits with a copy of `other`'s. The two are independent
afterwards, and this keeps its own capacity when that is the larger.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `other` | `Bitset` | read and not modified |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### `orWith` _method_
```nupp
orWith: function orWith(self, other: Bitset): nil
```
Adds every bit set in `other`.
One bitwise operation per word: the population is marked for recount
rather than tracked, and there is no per-word test for whether the word
changed, because that branch costs more than the write it saves.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `other` | `Bitset` | read and not modified |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### `andWith` _method_
```nupp
andWith: function andWith(self, other: Bitset): nil
```
Keeps only the bits also set in `other`.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `other` | `Bitset` | read and not modified. Words beyond the ones it uses are cleared, so an empty `other` empties the receiver. |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### `andNotWith` _method_
```nupp
andNotWith: function andNotWith(self, other: Bitset): nil
```
Removes every bit set in `other`.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `other` | `Bitset` | read and not modified. Words beyond the ones it uses keep their bits, so an empty `other` changes nothing. |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### `xorWith` _method_
```nupp
xorWith: function xorWith(self, other: Bitset): nil
```
Keeps only the bits set in exactly one of the two.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `any` | |
| `other` | `Bitset` | read and not modified |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
### `Key` _record_
```nupp
record Key ...
```
A typed identity for one value in a [`Store`](#nupp.util.Store).
#### Type parameters
| Name | Description |
| --- | --- |
| `T` | |
#### Members
| Name | Kind | Description |
| --- | --- | --- |
| [`Step`](#nupp.util.Key.Step) | type | The step of nupp.util.Key.registered. |
| [`id`](#nupp.util.Key.id) | field | |
| [`name`](#nupp.util.Key.name) | field | |
| [`find`](#nupp.util.Key.find) | method | Finds a registered key by name. |
| [`registered`](#nupp.util.Key.registered) | method | Walks every registered name, ascending by id. |
#### `Step` _type_
```nupp
type Step = function(any, integer): (integer, string)
```
The step of [`nupp.util.Key.registered`](#nupp.util.Key.registered).
Terminating on nil is the generic for's business, so the surface type
promises what the loop delivers rather than what the last call returns.
#### `id` _field_
```nupp
id: integer
```
`@readonly`
#### `name` _field_
```nupp
name: string?
```
`@readonly`
#### `find` _method_
```nupp
find: function find(name: string): unknown
```
Finds a registered key by name.
The registry knows the name's id and nothing about its type, so the
result is `unknown` and the caller casts to the `Key` it claims.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string` | the registered name |
##### Returns
| Type | Description |
| --- | --- |
| `unknown` | the key, or nil when the name is not registered |
#### `registered` _method_
```nupp
registered: function registered(): function(any, integer): (integer, string), any, integer
```
Walks every registered name, ascending by id.
The walk allocates nothing: the step is one shared function and the
control variable is the id it last reported. The registry itself is
never handed out, so nothing the loop is given can be used to reach or
change it. An anonymous key registers no name and is not walked.
##### Returns
| Type | Description |
| --- | --- |
| `function(any, integer): (integer, string)` | the step the loop calls |
| `any` | nothing to carry, since the ids are the whole state |
| `integer` | the id to resume after, 0 to start |
### `Pool` _record_
```nupp
record Pool ...
```
A pool of instances stamped with one record declaration.
#### Type parameters
| Name | Description |
| --- | --- |
| `T` | |
#### Members
| Name | Kind | Description |
| --- | --- | --- |
| [`witness`](#nupp.util.Pool.witness) | field | |
| [`capacity`](#nupp.util.Pool.capacity) | field | How many released instances the pool retains for reuse. |
| [`freeList`](#nupp.util.Pool.freeList) | field | |
| [`freeCount`](#nupp.util.Pool.freeCount) | field | |
| [`liveCount`](#nupp.util.Pool.liveCount) | field | |
| [`liveValues`](#nupp.util.Pool.liveValues) | field | |
| [`acquire`](#nupp.util.Pool.acquire) | method | Hands out an instance, from the free list or freshly stamped. |
| [`release`](#nupp.util.Pool.release) | method | Clears an instance and returns it to the free list. |
| [`reserve`](#nupp.util.Pool.reserve) | method | Stamps free instances until at least count are waiting. |
| [`live`](#nupp.util.Pool.live) | method | How many instances are acquired and not yet released. |
| [`free`](#nupp.util.Pool.free) | method | How many instances are waiting on the free list. |
| [`reset`](#nupp.util.Pool.reset) | method | Drops the free list. |
#### `witness` _field_
```nupp
witness: any
```
`@private` `@readonly`
#### `capacity` _field_
```nupp
capacity: integer
```
`@readonly`
How many released instances the pool retains for reuse.
#### `freeList` _field_
```nupp
freeList: {T}
```
`@private`
#### `freeCount` _field_
```nupp
freeCount: integer
```
`@private`
#### `liveCount` _field_
```nupp
liveCount: integer
```
`@private`
#### `liveValues` _field_
```nupp
liveValues: {[any]: boolean}
```
`@private`
#### `acquire` _method_
```nupp
acquire: function(exclusive self: Pool): T
```
Hands out an instance, from the free list or freshly stamped.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive self` | `Pool\` | |
##### Returns
| Type | Description |
| --- | --- |
| `T` | |
#### `release` _method_
```nupp
release: function(exclusive self: Pool, value: T): nil
```
Clears an instance and returns it to the free list.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive self` | `Pool\` | |
| `value` | `T` | |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
##### Raises
| Type | Condition |
| --- | --- |
| `string` | when nothing is live, or value was not stamped by the pool's declaration |
#### `reserve` _method_
```nupp
reserve: function(exclusive self: Pool, count: integer): nil
```
Stamps free instances until at least `count` are waiting.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive self` | `Pool\` | |
| `count` | `integer` | |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
##### Raises
| Type | Condition |
| --- | --- |
| `string` | when count is negative |
#### `live` _method_
```nupp
live: function(self: Pool): integer
```
How many instances are acquired and not yet released.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Pool\` | |
##### Returns
| Type | Description |
| --- | --- |
| `integer` | |
#### `free` _method_
```nupp
free: function(self: Pool): integer
```
How many instances are waiting on the free list.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Pool\` | |
##### Returns
| Type | Description |
| --- | --- |
| `integer` | |
#### `reset` _method_
```nupp
reset: function(exclusive self: Pool): nil
```
Drops the free list.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `exclusive self` | `Pool\` | |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
##### Raises
| Type | Condition |
| --- | --- |
| `string` | when any instance is live |
### `Store` _interface_
```nupp
interface Store ...
```
An independent typed bag indexed by keys.
#### Members
| Name | Kind | Description |
| --- | --- | --- |
| [`Step`](#nupp.util.Store.Step) | type | The step of nupp.util.Store.entries. |
| [`get`](#nupp.util.Store.get) | method | Answers the value held under a key. |
| [`set`](#nupp.util.Store.set) | method | Stores a non-nil value under a key. |
| [`remove`](#nupp.util.Store.remove) | method | Removes the value held under a key. |
| [`clear`](#nupp.util.Store.clear) | method | Removes every value without touching key registration. |
| [`entries`](#nupp.util.Store.entries) | method | Walks every occupied key ascending by id, without its value. |
#### `Step` _type_
```nupp
type Step = function(Store, integer): (integer, string?, string)
```
The step of [`nupp.util.Store.entries`](#nupp.util.Store.entries).
Terminating on nil is the generic for's business, so the surface type
promises what the loop delivers rather than what the last call returns.
#### `get` _method_
```nupp
get: function(self: Store, key: Key): T?
```
Answers the value held under a key.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Store` | |
| `key` | `Key\` | |
##### Returns
| Type | Description |
| --- | --- |
| `T?` | |
#### `set` _method_
```nupp
set: function(self: Store, key: Key, value: T): nil
```
Stores a non-nil value under a key.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Store` | |
| `key` | `Key\` | |
| `value` | `T` | |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
##### Raises
| Type | Condition |
| --- | --- |
| `string` | when value is nil; use [`nupp.util.Store.remove`](#nupp.util.Store.remove) to delete an entry |
#### `remove` _method_
```nupp
remove: function(self: Store, key: Key): nil
```
Removes the value held under a key.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Store` | |
| `key` | `Key\` | |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### `clear` _method_
```nupp
clear: function(self: Store): nil
```
Removes every value without touching key registration.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `self` | `Store` | |
##### Returns
| Type | Description |
| --- | --- |
| `nil` | |
#### `entries` _method_
```nupp
entries: function(
borrows self: Store
): (function(Store, integer): (integer, string?, string), Store borrows (self), integer)
```
Walks every occupied key ascending by id, without its value.
##### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `borrows self` | `Store` | |
##### Returns
| Type | Description |
| --- | --- |
| `function(Store, integer): (integer, string?, string)` | |
| `Store borrows (self)` | |
| `integer` | |
## Functions
### `fnv1a64` _function_
```nupp
function fnv1a64(borrows value: string | ByteView): string
```
Hashes bytes with FNV-1a over 64 bits, as sixteen hexadecimal digits.
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `borrows value` | `string | ByteView` | the bytes to hash |
#### Returns
| Type | Description |
| --- | --- |
| `string` | the hash, as sixteen lowercase hexadecimal digits |
### `newKey` _function_
```nupp
function newKey(name: string?): Key
```
Registers a new key, optionally under a name.
#### Type parameters
| Name | Description |
| --- | --- |
| `T` | |
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `name` | `string?` | the opaque name to register, or nil for an anonymous key |
#### Returns
| Type | Description |
| --- | --- |
| `Key\` | the key |
#### Raises
| Type | Condition |
| --- | --- |
| `string` | when the name is empty or already registered, before an id is used |
### `newPool` _function_
```nupp
function newPool(witness: Type, capacity: integer?): pool.Pool
```
Creates a pool of instances of one record type.
#### Type parameters
| Name | Description |
| --- | --- |
| `T` | |
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `witness` | `Type\` | the record declaration, whose metatable stamps every instance |
| `capacity` | `integer?` | how many released instances to retain, 32 when omitted |
#### Returns
| Type | Description |
| --- | --- |
| `pool.Pool\` | the pool, warmed to capacity |
#### Raises
| Type | Condition |
| --- | --- |
| `string` | when capacity is negative |
### `newStore` _function_
```nupp
function newStore(): Store
```
Creates an empty store.
#### Returns
| Type | Description |
| --- | --- |
| `Store` | the store |
### `try` _function_
```nupp
function try(f: function(A...): R, ...: A...): R?, unknown
```
Runs a function under `pcall`, answering `(result, raised)` rather than
`(ok, ...)`, which is the layout `or return` reads.
#### Type parameters
| Name | Description |
| --- | --- |
| `R` | |
| `A` | |
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `f` | `function(A...): R` | the function to run protected |
| `...` | `A...` | its arguments |
#### Returns
| Type | Description |
| --- | --- |
| `R?` | its result, or nil when it raised |
| `unknown` | the raised value, or nil when it did not |
### `tryWith` _function_
```nupp
function tryWith(f: function(A...): R, handler: function(any): E, ...: A...): R?, E?
```
The same for `xpcall`, with the handler after the function: it runs before the
stack unwinds and its result is the reason.
#### Type parameters
| Name | Description |
| --- | --- |
| `R` | |
| `E` | |
| `A` | |
#### Arguments
| Name | Type | Description |
| --- | --- | --- |
| `f` | `function(A...): R` | the function to run protected |
| `handler` | `function(any): E` | what to make of a raised value |
| `...` | `A...` | the function's arguments |
#### Returns
| Type | Description |
| --- | --- |
| `R?` | its result, or nil when it raised |
| `E?` | what `handler` made of the raised value, or nil when it did not raise |
### `uuid4` _function_
```nupp
function uuid4(): string
```
Generates a random version 4 UUID, hyphenated and lowercase.
#### Returns
| Type | Description |
| --- | --- |
| `string` | the UUID, hyphenated and lowercase |
#### Raises
| Type | Condition |
| --- | --- |
| `string` | when the provider fails or returns a malformed UUID |
### `uuid7` _function_
```nupp
function uuid7(): string
```
Generates a time-ordered version 7 UUID, hyphenated and lowercase.
Ordered to the millisecond only: two made in the same millisecond carry
random bits after the timestamp, so they compare in either order. It uses
no RFC 9562 monotonic counter.
#### Returns
| Type | Description |
| --- | --- |
| `string` | the UUID, hyphenated and lowercase |
#### Raises
| Type | Condition |
| --- | --- |
| `string` | when the provider fails or returns a malformed UUID |
## Values
### `WORD_BITS` _variable_
```nupp
const WORD_BITS
```
The bits one word of a [`Bitset`](#nupp.util.Bitset) holds.