Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

lib/array.x

Dynamic contiguous arrays of Var elements.

Primary API

FunctionSummary
Array.concatReturns a new Array holding the elements of a followed by those of b.
Array.containsReturns nonzero when some element of array equals value.
Array.copyReturns a new Array holding the same elements as array.
Array.countReturns how many elements compare equal to value.
Array.findReturns the index of the first element equal to value, or -1.
Array.getindexReturns the element at index, or void when index is out of range.
Array.getsliceReturns a new Array holding the elements array[start:end:step].
Array.indexofReturns Array.find(array, value).
Array.insertInserts elem at index and returns it, or void when out of range.
Array.iterInitializes dest as an iterator over the elements of x.
Array.joinJoins the elements of array into one String separated by separator.
Array.mapReturns a new Array holding func applied to each element of array.
Array.map2Maps func over corresponding elements up to the shorter Array.
Array.newReturns a fresh empty Array with its own identity.
Array.postfixindexApplies postfix Array element increment or decrement.
Array.pushAppends elem to the end of array and returns it.
Array.reduceLeft-folds a nonempty Array, or returns void when it is empty.
Array.removeRemoves and returns the element at index, or void when out of range.
Array.resizeResizes arr, truncating or appending Null elements as needed.
Array.reverseReverses array in place and returns that same Array.
Array.setindexStores elem at index and returns it, or void when out of range.
Array.setsliceReplaces the region array[start:end] with the elements of values and returns array.
Array.shiftRemoves and returns the first element of array, or void if it is empty.
Array.sortSorts array in place in ascending order and returns that same Array.
Array.spliceReplaces remove_count elements at index with values and returns what was removed.
Array.take_lastTakes and returns the last element of array, or void if it is empty.
Array.unshiftInserts elem at the front of array and returns it.
Array.updateindexUpdates one Array element in place.
Array.write_strAppends the Array display text to out, using each element’s write_str.
Block.arrayReturns the same object as an Array view; mutations remain shared.
Iter.arrayDrains 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

FunctionSummary
Array.compareCompares Arrays lexicographically with Var.compare.
Array.equalReturns nonzero when two Arrays have structurally equal elements.
Array.heap_popRemoves and returns the smallest element of heap, or void when it is empty.
Array.heap_pushAdds val to heap, an Array maintained as a binary min-heap.
Array.heapifyRearranges heap in place so that it satisfies the min-heap invariant.
Array.remsliceRemoves normalized bounds [start:end] and returns a fresh Array.
Array.reprReturns the readable [ a, b, c ] representation of array.
Array.strReturns an Array display String using each element’s str.
Array.update_nAppends exactly element_count variadic values to array.
Array.write_reprAppends 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.

FunctionSummary
Array.blockReturns 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

TypeKindSummary
ArrayaliasHolds 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.