lib/array.x
Dynamic contiguous arrays of Var elements.
Primary API
| Function | Summary |
|---|---|
Array.concat | Returns a new Array holding the elements of a followed by those of b. |
Array.contains | Returns nonzero when some element of array equals value. |
Array.copy | Returns a new Array holding the same elements as array. |
Array.count | Returns how many elements compare equal to value. |
Array.find | Returns the index of the first element equal to value, or -1. |
Array.foldl | Folds fn over array from seed, front to back. |
Array.getindex | Returns the element at index, or void when index is out of range. |
Array.getslice | Returns a new Array holding the elements array[start:end:step]. |
Array.indexof | Returns Array.find(array, value). |
Array.insert | Inserts elem at index and returns it, or void when out of range. |
Array.iter | Initializes dest as an iterator over the elements of x. |
Array.join | Joins the elements of array into one String separated by separator. |
Array.map | Returns a new Array holding func applied to each element of array. |
Array.map2 | Maps func over corresponding elements up to the shorter Array. |
Array.new | Returns a fresh empty Array with its own identity. |
Array.postfixindex | Applies postfix Array element increment or decrement. |
Array.push | Appends elem to the end of array and returns it. |
Array.remove | Removes and returns the element at index, or void when out of range. |
Array.resize | Resizes arr, truncating or appending Null elements as needed. |
Array.reverse | Reverses array in place and returns that same Array. |
Array.setindex | Stores elem at index and returns it, or void when out of range. |
Array.setslice | Replaces the region array[start:end] with the elements of values and returns array. |
Array.shift | Removes and returns the first element of array, or void if it is empty. |
Array.sort | Sorts array in place in ascending order and returns that same Array. |
Array.sort_by | Stably sorts array by keys produced once per value, returning the Array. |
Array.sort_with | Stably sorts array with a borrowed synchronous comparator and returns it. |
Array.splice | Replaces remove_count elements at index with values and returns what was removed. |
Array.take_last | Takes and returns the last element of array, or void if it is empty. |
Array.try_next | Writes the next element, advances cursor, and returns one. |
Array.unshift | Inserts elem at the front of array and returns it. |
Array.updateindex | Updates one Array element in place. |
Array.write_str | Appends the Array display text to out, using each element’s write_str. |
Block.array | Returns the same object as an Array view; mutations remain shared. |
Iter.array | Drains iter into a fresh Array. |
Array
Array.concat
Self Array.concat(Self a, Self b)
Returns a new Array holding the elements of a followed by those of b.
Neither input is modified and the result is a fresh object. A null or
empty b yields a copy of a.
Raises: <size-limit> or <alloc-fail> when the result cannot be
represented or allocated.
Source: lib/array.x:433
Array.contains
int Array.contains(Array array, Var value)
Returns nonzero when some element of array equals value.
Uses the same linear search and structural Var equality as Array.find.
Use a Map for frequent membership tests.
Raises: <size-limit> when array exceeds the INT_MAX index limit that
Array.getindex describes.
Source: lib/array.x:416
Array.copy
Self Array.copy(Self array)
Returns a new Array holding the same elements as array.
The copy is shallow and independent: pushing to one does not affect the
other, but the two share whatever objects their elements point at.
Because Arrays are identity-bearing, plain assignment aliases instead of
copying, so copy before handing scratch storage to code that may mutate
it.
Raises: <size-limit> or <alloc-fail> when the copy cannot be
represented or allocated.
Source: lib/array.x:311
Array.count
int Array.count(Array array, Var value)
Returns how many elements compare equal to value.
Source: lib/array.x:419
Array.find
int Array.find(Array array, Var value)
Returns the index of the first element equal to value, or -1.
The scan is linear and compares with Var equality, the same rule ==
applies to boxed values. Arrays and Maps participate
structurally, while
=== remains the identity test. Array.indexof is a synonym.
Raises: <size-limit> when array exceeds the INT_MAX index limit that
Array.getindex describes.
Source: lib/array.x:405
Array.foldl
Var Array.foldl(Array array, Var seed, Func fn)
Folds fn over array from seed, front to back.
A void seed means “no seed”: the first element becomes the accumulator
and the fold starts at the second, so folding an empty Array that way
returns void. Elements are passed as values. Input with nothing left to
fold does not invoke or check fn. The callback receives the accumulator
then the next element and is not retained. It must not structurally mutate
array during the walk. Any cause from Func.apply or fn propagates
without changing array.
Source: lib/array.x:498
Array.getindex
Var Array.getindex(Array array, int index)
Returns the element at index, or void when index is out of range.
This is what array[index] lowers to. A negative index counts from
the end, so -1 is the last element and -array.len() is the first.
An index that still falls outside the array after that normalization
yields void.
Array has no Array.try_get; the void result reports the miss. It is
unambiguous because void is excluded from the element domain. Raw Null
is Array data and reads back as itself.
Compound assignment and increment/decrement on an indexed Array become
single calls to Array.updateindex and Array.postfixindex. The read,
modify, and write happen in one call. That is not thread-safe
synchronization.
Array digits = [0, 1, 2, 3, 4, 5];
printf("%s %s\n", digits[0].repr(), digits[-1].repr());
printf("%s %s\n", digits[6].repr(), digits[-7].repr());
Raises: <size-limit> when array holds more than INT_MAX elements.
Source: lib/array.x:128
Array.getslice
Self Array.getslice(Self array, int start, int end, int step)
Returns a new Array holding the elements array[start:end:step].
This is what array[start:end:step] lowers to; a part omitted from that
literal form becomes the whole-array default. Negative bounds count from
the end and a negative step walks backwards, normalized the same way
List and String slicing normalize them, so the rules match across the
three types.
The result is a fresh Array, never a view, so later writes to either
side are invisible to the other. A range that selects nothing yields an
empty Array. Ask for the rest of an array by omitting the bound, as in
array[start:]. A forward end above the length is not clamped to it
and reads one element beyond the last.
Array digits = [0, 1, 2, 3, 4, 5];
printf("%s %s\n", digits[1:4].repr(), digits[3:].repr());
printf("%s %s\n", digits[::2].repr(), digits[::-1].repr());
Raises: <bad-arg> when step is zero, or <size-limit> when array
exceeds the INT_MAX index limit that Array.getindex describes.
Source: lib/array.x:336
Array.indexof
int Array.indexof(Array array, Var value)
Returns Array.find(array, value).
Source: lib/array.x:425
Array.insert
Var Array.insert(Array array, int index, Var elem)
Inserts elem at index and returns it, or void when out of range.
Elements at and after index move up one position. An insertion may
also land past the last element, so the accepted range is one wider than
for reading. index may equal array.len(), which appends.
Negative indices normalize against that wider range, so they do not line
up with Array.getindex. -1 appends at the end, -2 inserts before
the last element, and -(array.len() + 1) inserts at the front. Anything
further out inserts nothing and returns void.
Raises: <void-op> when elem is void and index is in range, or
<size-limit> when array exceeds the INT_MAX index limit that
Array.getindex describes, or <alloc-fail> when storage cannot grow.
These failures leave array unchanged.
Source: lib/array.x:278
Array.iter
Iter Array.iter(Array x, Iter dest)
Initializes dest as an iterator over the elements of x.
The caller owns the storage: declare a struct Iter and pass its
address. The return value is that same dest, or NULL when dest is
null, as in every iterator constructor in the library.
foreach (Var item, array) uses this, and the lazy combinators start
here.
The iterator borrows x and its stored Var values, so
the Array and any
pointed-to values used by the caller must remain live. An Iter is
single-pass, with no rewind, and any structural mutation of
the Array while
one is outstanding invalidates it. Iter.array is the other direction,
draining an iterator into a fresh Array, and Array.list converts to a
canonical List.
Source: lib/array.x:810
Array.join
String Array.join(Array array, String separator)
Joins the elements of array into one String separated by separator.
Elements are converted with their str form, so a String element
contributes its bytes without quotes and a number contributes its
digits. A null separator joins with nothing between elements, and an
empty array yields the empty String.
The receiver here is the Array. In String.join the separator is the
receiver and the elements arrive as a List. Raises: <alloc-fail> or
<size-limit> while rendering or canonicalizing the result, or a cause
from an element’s write_str.
Source: lib/array.x:719
Array.map
Array Array.map(Array array, Func func)
Returns a new Array holding func applied to each element of array.
array itself is untouched, and elements are passed as values. An empty
input returns a fresh empty Array without invoking or checking func.
The
callback is invoked front to back and is not retained. It must not mutate
array while the walk is in progress; Func rejects a void result.
Raises: whatever Func.apply or func raises, or an allocation cause
while constructing the result. The partial result is freed.
Source: lib/array.x:459
Array.map2
Array Array.map2(Array a, Array b, Func func)
Maps func over corresponding elements up to the shorter Array.
The callback receives left then right, runs front to back, and is not
retained. An empty input does not invoke or check it; neither input may be
structurally mutated during the walk.
Raises: whatever Func.apply or func raises, or an allocation cause
while constructing the result. The partial result is freed.
Source: lib/array.x:476
Array.new
Array Array.new(void)
Returns a fresh empty Array with its own identity.
The literal %[] calls this constructor. Test emptiness with Array.len.
Raises: <alloc-fail> if the backing Block cannot be allocated.
Source: lib/array.x:64
Array.postfixindex
Var Array.postfixindex(Array array, int index, Symbol op)
Applies postfix Array element increment or decrement.
The returned value is the original element. The slot remains unchanged if
the index or operation is invalid.
Raises: <bad-arg> for a null Array or invalid index,
<size-limit> when
its length cannot be indexed, or any cause from Var.postfix. The element
is unchanged on failure.
Source: lib/array.x:188
Array.push
Var Array.push(Array array, Var elem)
Appends elem to the end of array and returns it.
Returning the appended value lets a push be used directly in another
expression. The array grows as needed; capacity is an implementation
detail.
Array queue = [];
queue.push(10);
queue.push("twenty");
printf("%s\n", queue.repr().str());
Raises: <void-op> when elem is void, or <size-limit> when the
Array cannot grow within its index domain, or <alloc-fail> when storage
cannot grow. These failures leave array unchanged.
Source: lib/array.x:213
Array.remove
Var Array.remove(Array array, int index)
Removes and returns the element at index, or void when out of range.
Elements after index move down one position, so this is O(n) unless
index is the last one. Negative indices count from the end as in
Array.getindex, so -1 removes the last element. Array.insert uses
a different rule. An empty array yields void.
Raises: <size-limit> when array exceeds the INT_MAX index limit that
Array.getindex describes.
Source: lib/array.x:296
Array.resize
void Array.resize(Array arr, size_t size)
Resizes arr, truncating or appending Null elements as needed.
Raises: <size-limit> when size exceeds the Array index domain, plus
any cause from Block growth. Allocation and size failure do not return
here. A growth failure leaves the length and existing elements unchanged.
Source: lib/array.x:71
Array.reverse
Self Array.reverse(Self array)
Reverses array in place and returns that same Array.
To preserve the original order, slice with a negative step
(array[::-1]), which builds a fresh Array.
Source: lib/array.x:448
Array.setindex
Var Array.setindex(Array array, int index, Var elem)
Stores elem at index and returns it, or void when out of range.
This is what array[index] = elem lowers to. Negative indices count
from the end as in Array.getindex. An out-of-range index changes
nothing and is reported by the void result. setindex never grows the
array; use Array.push or Array.insert to add an element.
The bounds check runs before the value check, so an out-of-range write
of void returns void instead of failing.
Raises: <void-op> when elem is void and index is in range, or
<size-limit> when array exceeds the INT_MAX index limit that
Array.getindex describes.
Source: lib/array.x:148
Array.setslice
Self Array.setslice(Self array, int start, int end, Self values)
Replaces the region array[start:end] with the elements of values and
returns array.
The replacement need not match the length of the region it replaces.
The array grows or shrinks and the tail moves to fit. A null or empty
values deletes the region, and an empty region inserts.
Bounds are normalized exactly as array[start:end] normalizes them, so
the replaced region is the one that slice selects: start counts from the
end when negative, and a negative end is a stop, with -1 naming the
position after the last element. A reversed pair is swapped.
There is no step and no bracket spelling; array[start:end] = values
is not accepted, so call the method. Aliasing is handled, so passing
array as its own values copies first.
Raises: <size-limit> when either Array cannot be indexed or the result
cannot be represented, or <alloc-fail> while copying an aliased source
or growing. These failures leave array unchanged.
Source: lib/array.x:365
Array.shift
Var Array.shift(Array array)
Removes and returns the first element of array, or void if it is
empty.
Every remaining element moves down one position, so this is O(n) in the
length while Array.take_last is O(1). Pair Array.push with shift
for a FIFO queue and with Array.take_last for a stack.
Source: lib/array.x:243
Array.sort
Self Array.sort(Self array)
Sorts array in place in ascending order and returns that same Array.
Call Array.copy first to preserve the original order. Ordering is
Var.compare, which compares numbers numerically and Strings, Symbols,
and Atoms by content. The sort is qsort, so it is not stable, and a
null or one-element array is returned unchanged.
Array numbers = [5, 3, 9, 1];
Array sorted = numbers.sort();
printf("%s %d\n", numbers.repr(), sorted == numbers);
Raises: causes from element comparison. The Array may already be
partially
reordered when a catch receives the cause.
Source: lib/array.x:539
Array.sort_by
Self Array.sort_by(Self array, Func key)
Stably sorts array by keys produced once per value, returning the Array.
The borrowed callback runs front to back and must not mutate this Array.
Keys use Var.compare; equal keys preserve the original element order.
A null or empty Array invokes no callback. Sorting another Array inside
the callback is valid. Raises: allocation, key comparison, Func.apply,
or callback causes. Failure leaves the original Array unchanged;
callback side effects are not undone.
Source: lib/array.x:605
Array.sort_with
Self Array.sort_with(Self array, Func compare)
Stably sorts array with a borrowed synchronous comparator and returns it.
The callback receives two values; its result converts to int, with a
negative, zero, or positive result ordering the first before, equal to,
or after the second. It must give a consistent ordering and must not
mutate this Array. Sorting a different Array inside the callback is valid.
Null and fewer than two elements return unchanged without a callback.
Raises: allocation, Func.apply, conversion, or callback causes. Failure
leaves the original Array unchanged; temporary storage is released.
Callback side effects are not undone.
Source: lib/array.x:560
Array.splice
Self Array.splice(Self array, int index, int remove_count, Self values)
Replaces remove_count elements at index with values and returns
what was removed.
The returned Array is fresh and holds the removed region in order.
index is normalized as a slice bound, so a negative value counts from
the end and a value past the end clamps to it. A remove_count of zero
or less removes nothing, making splice an insertion; a null values
makes it a deletion.
Raises: <size-limit> when either Array or the result cannot be
represented, or <alloc-fail> while copying or growing. These failures
leave array unchanged.
Source: lib/array.x:391
Array.take_last
Var Array.take_last(Array array)
Takes and returns the last element of array, or void if it is empty.
With Array.push this makes a stack. Both work at the end of the array,
move no other elements, and are amortized O(1). Capacity is retained
after taking the element, so taking and pushing again does not
reallocate.
Source: lib/array.x:229
Array.try_next
int Array.try_next(Array array, int *cursor, Var *out)
Writes the next element, advances cursor, and returns one.
Initialize the caller-owned cursor to zero. A null Array, a null
pointer, a negative cursor, or exhaustion returns zero without changing
cursor or out. Structural mutation invalidates an outstanding cursor.
foreach (Var item, array) compiles to this loop.
Raises: <size-limit> for an Array outside the integer index domain.
Source: lib/array.x:786
Array.unshift
Var Array.unshift(Array array, Var elem)
Inserts elem at the front of array and returns it.
Existing elements move up one position, so this is O(n); Array.push is
the amortized O(1) end of the array. Returning elem lets an unshift
be used directly in another expression, as Array.push does.
Raises: <void-op> when elem is void, or <size-limit> when the
Array cannot grow within its index domain, or <alloc-fail> when storage
cannot grow. These failures leave array unchanged.
Source: lib/array.x:256
Array.updateindex
Var Array.updateindex(Array array, int index, Symbol op, Var rhs)
Updates one Array element in place.
The index is normalized once, including negative indexing, and the
element slot is delegated to Var.update. The stored Var tag is
therefore preserved and the slot remains unchanged on failure.
Raises: <bad-arg> for a null Array or invalid index,
<size-limit> when
its length cannot be indexed, <void-op> for a void right operand, or
any cause from Var.update. These failures leave the element unchanged
.
Source: lib/array.x:168
Array.write_str
Buffer Array.write_str(Array a, Buffer out)
Appends the Array display text to out, using each element’s
write_str.
Array.str materializes this into a String.
Source: lib/array.x:741
Block
Block.array
inline Array Block.array(Block x)
Returns the same object as an Array view; mutations remain shared.
Source: lib/array.x:58
Iter
Iter.array
Array Iter.array(Iter iter)
Drains iter into a fresh Array.
Source: lib/array.x:816
Advanced and interop API
| Function | Summary |
|---|---|
Array.cleanup | Ends the owned lifetime when a managed local leaves its block. |
Array.compare | Compares Arrays lexicographically with Var.compare. |
Array.equal | Returns nonzero when two Arrays have structurally equal elements. |
Array.heap_pop | Removes and returns the smallest element of heap, or void when it is empty. |
Array.heap_push | Adds val to heap, an Array maintained as a binary min-heap. |
Array.heapify | Rearranges heap in place so that it satisfies the min-heap invariant. |
Array.remslice | Removes the region array[start:end] and returns a fresh Array. |
Array.repr | Returns the readable [ a, b, c ] representation of array. |
Array.str | Returns an Array display String using each element’s str. |
Array.update_n | Appends exactly element_count variadic values to array. |
Array.write_repr | Appends the readable Array representation to out. |
Array
Array.cleanup
void Array.cleanup(Array value)
Ends the owned lifetime when a managed local leaves its block.
Source: lib/array.x:824
Array.compare
int Array.compare(Array a, Array b)
Compares Arrays lexicographically with Var.compare.
Source: lib/array.x:518
Array.equal
int Array.equal(Array a, Array b)
Returns nonzero when two Arrays have structurally equal elements.
Source: lib/array.x:732
Array.heap_pop
Var Array.heap_pop(Array heap)
Removes and returns the smallest element of heap, or void when it is
empty. The remaining elements are re-heaped in O(log n), so repeated calls
yield ascending order and draining a heap is a sort. An Array that never
satisfied the heap invariant gives a meaningless answer instead of an
error. Call Array.heapify first if it was not built with
Array.heap_push.
Raises: any cause reported by element comparison while restoring the heap. The heap may already have removed its root when a catch receives the error.
Source: lib/array.x:685
Array.heap_push
void Array.heap_push(Array heap, Var val)
Adds val to heap, an Array maintained as a binary min-heap.
The heap operations arrange an Array as a priority queue in place, with
no second data structure and no extra allocation. The elements stay in
the Array with the smallest at index 0. Ordering is Var.compare, the
same rule Array.sort uses.
heap_push and Array.heap_pop maintain the invariant, but the
positional operations do not. After a plain Array.push, an assignment
through Array.setindex, or any slicing, call Array.heapify before
popping again.
Array heap = [];
heap.heap_push(30);
heap.heap_push(10);
heap.heap_push(20);
printf("%s %s\n", heap.heap_pop().repr(), heap.heap_pop().repr());
Raises: <void-op> when val is void, or <size-limit> when the heap
cannot grow within the Array index domain, <alloc-fail> when storage
cannot grow, or a cause from element comparison. A value or earlier swap
may remain when comparison fails; pre-insertion failures leave the heap
unchanged.
Source: lib/array.x:671
Array.heapify
void Array.heapify(Array heap)
Rearranges heap in place so that it satisfies the min-heap invariant.
Use this before the first Array.heap_pop on an Array that was built by
Array.push, read in from somewhere else, or disturbed by a positional
operation. It is O(n), cheaper than pushing the same elements one at a
time.
Raises: <size-limit> when heap exceeds the INT_MAX index limit that
Array.getindex describes, or a cause from element comparison. Comparison
failure may leave a partially rearranged Array.
Source: lib/array.x:704
Array.remslice
Self Array.remslice(Self array, int start, int end)
Removes the region array[start:end] and returns a fresh Array.
Bounds are normalized the way that slice normalizes them, so a negative
end is a stop. A reversed pair is swapped. Allocation or size failure
occurs before array is changed.
Source: lib/array.x:375
Array.repr
String Array.repr(Array array)
Returns the readable [ a, b, c ] representation of array.
Each element is rendered with its own repr, so Strings appear quoted
and Symbols in angle brackets. The result is for reading and for
diagnostics; unlike the List reader syntax it does not round-trip back
through a parser. An empty Array renders as [ ].
Array.str has the same shape but uses each element’s str form.
Array.write_repr and Array.write_str append to a Buffer instead of
allocating a String, and the two String forms are built on them.
Raises: <alloc-fail> or <size-limit> while constructing the result.
Source: lib/array.x:761
Array.str
String Array.str(Array array)
Returns an Array display String using each element’s str.
Source: lib/array.x:744
Array.update_n
Self Array.update_n(Self array, unsigned element_count, ...)
Appends exactly element_count variadic values to array.
Values appended before a later <void-op>, <size-limit>, or
<alloc-fail> remain in array. The caller must supply that many Var
arguments.
Source: lib/array.x:95
Array.write_repr
Buffer Array.write_repr(Array a, Buffer out)
Appends the readable Array representation to out.
Source: lib/array.x:735
Runtime-internal callables
These callables connect runtime translation units. They are documented for source readers but are not supported as user API.
| Function | Summary |
|---|---|
Array.block | Returns the same object as a Block view; no copy or transfer occurs. |
Array
Array.block
inline Block Array.block(Array x)
Returns the same object as a Block view; no copy or transfer occurs.
Source: lib/array.x:56
Public types
| Type | Kind | Summary |
|---|---|---|
Array | alias | Holds a mutable identity-bearing sequence of non-void Var elements. |
Array
typedef Block Array
Holds a mutable identity-bearing sequence of non-void Var elements.
Array is the same object as its Block view; that object and its backing
storage belong to the Scope active at construction.
Assignment aliases it;
Array.copy creates a new container, but still borrows any objects
referenced by its elements. Array.free invalidates all aliases.
Source: lib/array.x:35
Design notes
Array is mutable, identity-bearing contiguous Var storage over Block.
Every constructor returns an allocated object, including for an empty
Array; assignment aliases that object, while Array.copy makes a shallow
independent container. Scope owns its allocation unless Array.free
shortens the lifetime. Array data may contain raw Null but never
void.
The declared Block protocol supplies Array’s generated truth, pop,
free, and truncate members. Array.pop discards the final element;
Array.take_last removes and returns it.
Indexing and slicing normalize negative positions here. Positional mutation preserves the object identity, and structural mutation invalidates outstanding iterators.
Tests and examples
make verify (unittest/test-array.x) and make examples.