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.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.reduce | Left-folds a nonempty Array, or returns void when it is empty. |
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.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.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:427
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:410
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:309
Array.count
int Array.count(Array array, Var value)
Returns how many elements compare equal to value.
Source: lib/array.x:413
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:399
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:126
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:334
Array.indexof
int Array.indexof(Array array, Var value)
Returns Array.find(array, value).
Source: lib/array.x:419
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:276
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:708
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:629
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:453
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:470
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:62
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:186
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:211
Array.reduce
Var Array.reduce(Array array, Func func)
Left-folds a nonempty Array, or returns void when it is empty.
Elements are passed as values. An empty or one-element Array does not
invoke or check func. Otherwise the callback receives the accumulator
then each remaining element, runs front to back, and is not retained. It
must not structurally mutate array during the walk. Any cause from
Func.apply or func propagates without changing array itself.
Source: lib/array.x:490
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:294
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:69
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:442
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:146
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 as slice bounds, and 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:360
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:241
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:528
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:385
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:227
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:254
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:166
Array.write_str
Buffer Array.write_str(Array array, 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:654
Block
Block.array
inline Array Block.array(Block x)
Returns the same object as an Array view; mutations remain shared.
Source: lib/array.x:56
Iter
Iter.array
Array Iter.array(Iter iter)
Drains iter into a fresh Array.
Source: lib/array.x:714
Advanced and interop API
| Function | Summary |
|---|---|
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 normalized bounds [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.compare
int Array.compare(Array a, Array b)
Compares Arrays lexicographically with Var.compare.
Source: lib/array.x:507
Array.equal
int Array.equal(Array a, Array b)
Returns nonzero when two Arrays have structurally equal elements.
Source: lib/array.x:644
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:595
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:581
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:614
Array.remslice
Self Array.remslice(Self array, int start, int end)
Removes normalized bounds [start:end] and returns a fresh Array.
A reversed pair is swapped. Allocation or size failure occurs before
array is changed.
Source: lib/array.x:369
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:675
Array.str
String Array.str(Array array)
Returns an Array display String using each element’s str.
Source: lib/array.x:658
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:93
Array.write_repr
Buffer Array.write_repr(Array array, Buffer out)
Appends the readable Array representation to out.
Source: lib/array.x:647
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:54
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.