kota's memex
use fmt;

export fn main() void = {
	let x: [_]int = [1, 3, 3, 7];
	assert(len(x) == 4);
	assert(x[3] == 7);
	x[3] = 8;
	assert(x[3] == 8);

	let y: [1024]int = [1, 3, 3, 7, 42...]; // Fill remainder with 42

	printvals(y[..4]);
	printvals(y[2..8]);
};

fn printvals(in: []int) void = {
	fmt::println("input: {} integers", len(in))!;
	for (let i = 0z; i < len(in); i += 1) {
		fmt::printfln("in[{}]: {}", i, in[i])!;
	};
	fmt::println()!;
};

Arrays store a specified (determined at compile-time) number of ordered values of a uniform subtype; slices store an arbitrary (determined at runtime) number of ordered values of a uniform type.

initialization

an array may be declared with a specific length and subtype (e.g. [5]int), or may infer the length from context using an underscore (e.g. [_]int). A slice type leaves the length unwritten: []int. Values of a slice or an array type can be indexed to obtain the value of one of their objects, numbered from zero, with the [index] operator as shown in the sample. The length (number of items) of an array or slice may be obtained with the len built-in.

Like all values, arrays must be initialized when they are declared. This can be awkward for large arrays like y. In such cases, the ... operator is often useful: it assigns all remaining values to the last value. In this example, most of "y" is initialized to 42.

slicing

A slicing expression is used to "slice" arrays and slices with the .. operator. This creates a new slice which references a subset of the source object, such that y[2..5] will produce a slice whose 0th value is the 2nd value of "y" with a length of 5 - 2 = 3. Slicing does not copy the underlying data, so modifying the items in a slice will modify the underlying array.

pre-filled slice

let x: []int = alloc([1, 2, 3]);

// vs

let y: []int = [];
append(y, 1);
append(y, 2);
append(y, 3);

bounds checking

Accesses to arrays and slices are bounds checked, which means that accessing a value beyond the end of their objects will cause your program to abort.

let x = [1, 2, 3];
x[4] // ABORT!

It is occasionally useful (but risky!) to skip the bounds check, for interop with code written in other languages, or in carefully reviewed, performance critical code. To disable bounds checking place a * in the array length:

let x: [*]int = [1, 2, 3];
x[4]; // Undefined behavior!