Atoll has three core sequence type forms.
| Form | Kind | Length | Ownership |
|---|---|---|---|
List[T] or []T |
Growable list | Runtime, mutable | Owns backing storage |
[N]T |
Fixed array | Compile-time N |
Value |
Slice[T] or [..]T |
View | Runtime, non-growing | Borrows/pins backing storage |
All are homogeneous: every element has type T.
Lists
List[T] is the nominal type; []T is its preferred type sugar.
names: []string = ["Ada", "Grace"]Square-bracket literals construct lists when the expected type is growable.
numbers := [1, 2, 3]An empty literal needs an element constraint.
empty: []int = []Later use can sometimes infer the element type.
mut values := []
values.add(42)Lists are mutable only through a mutable place and a mutating method.
mut values := [1, 2]
values.add(3)
values.set(0, 10)Indexing is total in the current collection contract: safe lookup yields an optional value. Use pattern matching, option propagation, or an explicit fallback.
first := values.get(0)The library chapter documents the full API in Lists.
Constructors
[]T() constructs an empty list, and an integer argument supplies an initial
capacity hint.
empty := []int()
buffer := []byte(4096)This syntax desugars to the generic List.new[T](capacity) constructor.
same := List.new[int]()
reserved := List.new[byte](4096)Capacity reserves storage; it does not change the list’s logical length.
Arrays
[N]T has a compile-time length that participates in its type.
octets: [4]byte = [127, 0, 0, 1]The literal must contain exactly N elements.
invalid: [3]int = [1, 2] // errorThe length may be an integer constant.
const WIDTH = 4
row: [WIDTH]byte = [0, 0, 0, 0]Use arrays for protocol fields, fixed vectors, and layouts where extent is part of the contract. Use a list when length changes at runtime.
Slices
Slice[T], written [..]T, is a non-growing view into contiguous elements.
fn checksum(input: [..]byte): u64 {
// ...
}A slice carries a range and keeps the relevant backing storage valid. It does not own a separate growable buffer.
Create a safe view with slice(range). Invalid bounds return None.
middle := values.slice(1..3)Re-slicing a slice creates another view. A view can read or update in-range elements when reached through a mutable contract, but it cannot append or reserve capacity.
Growth
Growing a list may move or replace its backing storage. Existing slices retain the storage/range they were created from and remain safe; they do not magically expand with the owner’s new length.
This is why a slice carries view semantics rather than being another spelling for a list.
Iteration
Lists, arrays, and slices participate in for iteration when their Iterable
implementation is available.
for value in values {
consume(value)
}Iteration binds elements according to the sequence and loop mutability rules.
Use for mut value in values only when the implementation provides supported
write-through element semantics.
Conversion
Converting a slice to an owned list requires copying the viewed elements. Cloning a list creates an independent backing collection; ordinary value flow may share managed storage according to the value semantics in Values.
Byte lists and byte slices are the binary-data forms []byte and [..]byte.
The retired nominal bytes type should not appear in new APIs.