Arrays are a family of types used to package together multiple, indexable values that are all of the same type.
The basic idea is that the internal behavior of square brackets for indexing changes based on type, but appears semantically equivalent to the programmer. If it is declared as a fixed-size array, bounded-pointer, or bounded-reference, the behavior is hard coded into the compiler. For all other types (particularly structs), the square brackets invoke the type's overloaded '' method for both get and set operations.
There are many variations of built-in array types, distinguished by how they are declared:
- Vec: Variable-size arrays
- Map: Variable-size associated arrays
- Fixed-size arrays (C-style)
- Bounded pointer arrays
- Bounded-reference arrays
Additional array structures can be defined using templates and/or structs that build off the latter three array capabilities.
Vec: Variable-size arrays
Vec is the language standard template for a resizeable array. For ease-of-use, the language supports sugar for its use:
vec_array [u32] i32 // Equivalent to Vec[i32, u32]
The dimension must be an unsigned integer.
Map: Variable-size associated arrays
Map is the language standard template for a resizeable dictionary map. For ease-of-use, the language supports sugar for its use:
map_marray [Text] i32 // Equivalent to Map[i32, Text, usize]
The dimension here must be a type that supports the hash method.
Fixed-size arrays declare the size of the array using a constant, unsigned integer:
mut c_array  i32
Every attempt to index into such an array is automatically bounds-checked by its known size. (Note: This bounds check is not performed within a trust block.)
The declaration for a bounded-pointer array always occurs within a struct. For example:
struct VarArray size u32 data *[size] i32 // <-- bounded-pointer array
TBD. Distinguish when to use bounded-pointers vs. bounded-references. Also, bounded-pointers can never be indexed outside a trust block which trips up bounds-checking!
The compiler recognizes this as a bounded-pointer array because the declared size of the array references the field that declares the array's size as an unsigned integer. Naming the companion field that specifies the array's size brings two advantages to the compiler:
- It can automatically calculate the correct bounds check (0 <= i < size)
- It can mark the struct's type as having dependent values. This ensures we cannot obtain borrowed internal references to the struct if it has the mut permission.
Applying square brackets to the 'data' field is treated like a pointer that is bounds-checked. The bounds check happens automatically, but only if not within a trust block.
Note: Apply the square brackets to an instance of VarArray invokes the '' method defined for VarArray, which may or may not then invoke  on the data field. Bounded-pointer arrays are a good mechanisms for implementing various variable-size array structures, and is what lies behind the Vec template (which adds a capacity field).
This is similar to bounded-pointer arrays:
struct Slice offset usize size usize ref &[u32] i32
This is important for implementing slices via templates. In this case we have a borrowed (no allocator) reference with a known lifetime into some fixed or var size array. As shown, the Slice template takes advantage of this construct.