Documentation/Reference

Compiler-shipped collection families

On this page

These APIs ship in the compiler’s embedded first-party BASIL library. No import, generated Integer/String variant, or application .blib dependency is required. The algorithms use ordinary specialized records, checked borrows and storage exchange; they are not separate opaque runtime implementations. See core lists/sets/dictionaries and generic records .

Construction and ownership

DIM jobs AS Deque[STRING]=NewDeque()
PushBack(BYREF jobs,"build")
PushFront(BYREF jobs,"check")
PRINT PopFront(BYREF jobs)

cache=NewCache(100) AS Cache[STRING,LIST OF INTEGER]
CachePut(BYREF cache,"numbers",[1,2,3])

Empty factories need their type arguments from a typed destination or AS result annotation. Later mutations do not infer an earlier declaration’s type. Length is the logical element count for these records; LEN remains the core sequence/ hash-container operation. Reset(BYREF collection) empties a collection; it does not change its configuration. Ordinary parameters borrow, BYREF excludes other access, and copying copyable containers/snapshots creates independent values.

Insertion takes a BYVAL payload: it copies a borrowed copyable value once, adopts a fresh value, or adopts an explicitly transferred named owner. There is no last-use resource transfer. Resource payloads make their containing collection noncopyable. Pop, extraction and bounded-deque eviction return owned values; resource Front/Back/Peek/Lookup/Find/Get return checked read-only views. A view excludes mutation, transfer and relocation of its whole owner until consumption finishes, including suspension. Store a snapshot only for copyable payloads.

DIM files AS Deque[File]=NewDeque()
PushBack(BYREF files,OpenFile("/dev/null"))
PRINT GetFileInfo(Front(files)).Size
file=PopFront(BYREF files)   ' transfer out; normal scope cleanup closes it

Keys must be copyable and support the existing canonical equality/hash/order rules. Structural NaN keys are rejected with InvalidKeyError; signed zero is one key. Sorted containers use Compare and existing NaN-last ordering, after key validation. Custom Equal/Hash/Compare must agree. Resource keys and stored task/channel capabilities remain unsupported.

Opaque container fields are private implementation state. Automatic JSON/shared serialization cannot expose or manufacture that state: it raises JsonError code4. Encode a logical snapshot, or configure a concrete formatter that decodes through the public factories/operations. This also applies to other opaque types without declared formatters. Generic OPERATOR declarations remain unsupported; do not treat derived representation equality/hash as abstract sequence/cache equality. For logical deque/queue comparison, compare their copyable snapshots explicitly.

Sequences and priority queues

Type / factory Operations Cost and behavior
Deque[T], NewDeque() Length, PushFront/PushBack, Front/Back, PopFront/PopBack, Snapshot, Reset Circular buffer; amortized O(1) insertion/removal at either end; O(n) growth/snapshot/reset
Queue[T], NewQueue() Length, Enqueue, Front, Dequeue, Snapshot, Reset FIFO over a deque
BoundedDeque[T], NewBoundedDeque(capacity) Deque operations plus Capacity Positive capacity; inserting at a full end returns the owned OPTIONAL eviction from the opposite end; otherwise NONE
PriorityQueue[T], NewPriorityQueue() Length, Push(BYREF q,priority,value), Peek, PeekPriority, PopPriority, Reset Binary min-heap, signed INTEGER priority; O(log n) push/pop, O(1) peek; equal-priority order unspecified

Deque/queue/heap empty reads and removals raise EmptyCollection. Bounded-deque construction rejects nonpositive capacity with CollectionError; its pushes also declare CollectionError/EmptyCollection. Snapshots preserve logical sequence order and require copyable payloads. Priorities include INT64_MIN/MAX without negation. Heap payloads need no comparison operation. Growth and sifting exchange complete values rather than cloning their managed fields or resources.

Ordered keys and counting

Existing SET/DICT preserve insertion order; NewOrderedSet() and NewOrderedDictionary() are contextual factories for those same native types.

Type / factory Operations
SortedSet[T], NewSortedSet() Length, Has, InsertValue, RemoveValue, At(index), LowerBoundIndex(value), Range(first,finish), Snapshot, Reset; SetUnion/SetIntersection/SetDifference/SetSymmetricDifference
SortedDictionary[K,V], NewSortedDictionary() Length, Has, SetValue(key,value), Lookup(key), LookupRequired(key), RemoveValue(key), Extract(key), KeySnapshot, ValueSnapshot, RangeKeys(first,finish), Reset; resource Values view
Counter[T], NewCounter() Length, Count(key), TotalCount, Add(key,amount=1), RemoveValue(key,amount=1), KeySnapshot, Reset
MultiMap[K,V], NewMultiMap() Length, TotalCount, Add(key,value), Has, Find, Get, GetAll, RemoveOne(key,value), RemoveKey(key), Extract(key), ExtractAt(key,index), KeySnapshot, Reset

Sorted keys use binary search, O(log n) lookup and O(n) insertion/removal in a sorted vector. Ranges are half-open [first,finish); reversed ranges are empty. Sorted-set algebra merges in O(n+m). InsertValue/SetValue return TRUE for a new key, FALSE for an existing one. Lookup returns OPTIONAL; LookupRequired raises MissingKey. At and editing APIs use nonnegative checked indices and IndexError. Key/order errors remain in specialized FAILS contracts.

Counter counts are positive; missing keys read as zero and zero counts remove the key. Add/RemoveValue require nonnegative amounts. Removal returns the amount removed, bounded by the current count. Length counts distinct keys; TotalCount counts occurrences. Overflow/invalid amounts raise CollectionError before mutation.

Multimaps retain duplicate values and per-key insertion order. Length counts keys, TotalCount counts all values; removing the last value removes the key. Get raises MissingKey; GetAll returns an independent list or an empty list and requires copyable values. Find/Get can borrow resource buckets. RemoveOne uses equality and requires copyable values; RemoveKey destroys all values and returns their count. Extract returns an owned optional bucket; ExtractAt removes one owned value. Key snapshots retain native insertion order; sorted-dictionary snapshots are sorted. ValueSnapshot is copyable-only; Values on a resource sorted dictionary is a view.

Bitsets

NewBitSet(size) creates a packed UINT64 fixed universe [0,size). Capacity is the universe size; Length counts included bits. Has/Include/Exclude/Flip use checked nonnegative indices and IndexError. Members returns ascending INTEGER indices. Reset clears bits without changing the universe. BitUnion, BitIntersection, BitDifference, BitSymmetricDifference and Complement return independent bitsets. Binary operations require equal universes (CollectionError). Complement masks unused padding bits. There is no arbitrary 100-million-bit cap; negative sizes are checked, while ordinary allocation/representability limits retain the fatal allocation policy. Storage is ceil(size/64)*8 payload bytes, plus ordinary list/record headers.

Bounded caches

DIM cache AS Cache[STRING,STRING]=NewCache(100,CachePolicy.LRUWithTTL,SOME(Seconds(60)))
result=CachePut(BYREF cache,"key","value",weight=2)
IF LET value=CacheFind(BYREF cache,"key") THEN
    PRINT value
END IF
Operation Behavior
NewCache(maxEntries,policy=LRU,expireAfter=NONE,maxWeight=0) Positive entry bound; weight0 disables the weight bound; TTL requires a positive Duration, plain LRU forbids one
NewTimedCache(maxEntries,policy,expireAfter,now,maxWeight=0) TTL/LRUWithTTL with caller-supplied MonotonicInstant samples
CachePut(BYREF cache,key,value,weight=1) Insert/replace, prune expired entries, then evict to satisfy both bounds; CachePutResult has Inserted, Evicted, Expired
CacheFind(BYREF cache,key) Prune, return OPTIONAL; refresh recency for LRU/LRUWithTTL
CachePeek(cache,key) Read-only OPTIONAL; neither prune nor refresh recency
CacheExtract(BYREF cache,key) Remove/return an owned OPTIONAL
CacheRemove(BYREF cache,key) Destroy/remove, return presence
PruneExpired(BYREF cache) Destroy expired entries; return removed count
CacheCount(BYREF cache) Prune, then return live count
ResidentCount / ResidentWeight Stored accounting including entries not yet pruned; no clock read
CacheCapacity / CacheWeightLimit Configuration, no clock read
Reset(BYREF cache) Release entries; preserve bounds, policy and accepted time domain

Every timed operation has an At counterpart with now AS MonotonicInstant after key/value and before optional weight. An externally timed cache requires At operations; ordinary caches reject them. LRU reads no clock. Other ordinary caches sample the system monotonic clock. Caller-owned Clock values can supply samples for active/boot/test time without transferring or copying clock authority.

TTL expires at age >= expireAfter, measured since the most recent write. Find does not extend TTL. TTL evicts oldest writes; LRU policies evict least recently used entries. Expiry order and recency have separate linked indexes; lookups/edits are amortized O(1), plus entries pruned/evicted. Freed slots are reused. Weights are caller accounting units, not measured memory usage.

Accepted mutating samples must be nondecreasing and from the same clock domain. Wrong domains, backwards samples, invalid mode/weights and weight-total overflow produce checked errors. A Peek validates time but does not advance LastObserved. Expired entries can be pruned before a later rejected write; this is not a full rollback transaction. APIs declare CollectionError/DateTimeError/IoError and key-dependent errors; plain LRU construction itself only declares CollectionError.

These are ordinary exclusive mutable values: no implicit locks, worker thread, timer task, asynchronous loader or request coalescing. Cancellation follows structured scope exit and cleans retained/temporary owners; a cancelled edit is not a recoverable transaction that resumes the same invocation.

From the BASIL documentation. View source ↗

Find your way around BASIL

Type to search the manual.