Skip to content

Sequences

Distinguish growable lists, fixed arrays, and borrowed slices.

Updated View as Markdown

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] // error

The 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.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close