Text and collections
AEL, the Agent Engineering Language, has three built-in collections, and each has a fixed capacity written in its type. Memory use is predictable: nothing grows behind your back, a full collection returns an explicit result, and small devices need no heap.
| Type | Holds | Size |
|---|---|---|
[T; N] | Exactly N values of type T. | Fixed: always N values. |
Vec<T, N> | Up to N values of type T, in order. | From zero to N values. |
Str<N> | UTF-8 text of up to N bytes. | From zero to N bytes. |
Capacity
- The capacity
Nof a list or a text value is a whole number known when you check your code. It must fit au32, at most 4,294,967,295, and the largest object the target allows. - An array's length
Nis also known when you check your code, and must fit the largest object the target allows. - A list or a text value reserves room for its full capacity, whether or not that room is used. A
Vec<Order, 100>takes room for 100 orders even when it is empty, so choose capacities that match your data. - Nothing grows past its capacity, and nothing is allocated when a value is added.
- Lengths and counts are
u32values.
Lists
A Vec<T, N> starts empty and holds its values in the order they were added. The standard library provides these operations:
| Operation | Returns | When it cannot |
|---|---|---|
| Create an empty list | An empty Vec<T, N> of the type its place expects. | — |
| Add a value at the end | Result<(), T> | The list is full. The error gives your value back, and the list stays unchanged. |
| Remove the value at an index | Result<T, IndexError>, with the removed value. The values after it move down one place. | The index is not less than the number of values: IndexError::OutOfBounds, and the list stays unchanged. |
| Count the values | u32 | — |
list[i] reads or writes one value. The index is checked against the number of values the list holds before the access; an index out of range, a negative one included, stops the program. Where an index may be out of range, compare it with the count first.
Text
Str<N> holds text as UTF-8 bytes, and it is always valid UTF-8. Its length is counted in bytes, not characters: "é" is two bytes.
| Operation | Returns | When it cannot |
|---|---|---|
| Count the bytes | u32 | — |
| Read one byte | Result<u8, IndexError> | The index is not less than the length: IndexError::OutOfBounds. |
| Append another text value | Result<(), CapacityError> | There is not room for all of it: CapacityError::Full. Nothing is appended, not even part of it. |
| Make text from an array of bytes | Result<Str<N>, StringError> | The bytes are not valid UTF-8: StringError::InvalidUtf8, checked over the whole input first. The text is valid but longer than N bytes: StringError::Full. |
- A text literal must fit its type.
let code: Str<4> = "ABCDE";is refused when you check your code. - Text has no index operator and no slices, and it is never indexed by character. A byte read from text is a byte, never taken for a whole character.
- The escapes you can write in a text literal are listed in Syntax basics.
Arrays
[T; N] holds exactly N values, and its length is part of its type.
- An array literal lists every value:
[12, 7, 30]is a[i64; 3]when nothing says otherwise. []is an empty array, and needs a type such as[u8; 0]from its place.scores[i]is checked against the length before the access, like a list index.
An example
struct Ticket {
id: u64,
subject: Str<120>,
tags: Vec<Str<16>, 8>,
}
fn middle(scores: [u32; 3]) -> u32 {
return scores[1];
}
fn example() -> u32 {
let scores: [u32; 3] = [12, 7, 30];
return middle(scores);
}
A Ticket holds a subject of up to 120 bytes and up to eight tags of up to 16 bytes each, and its size is known before the program runs.
Moving and copying
- Text and lists move: passing one to a function, assigning it or putting it into a struct or a message moves it, and the old place is not usable until it receives a new value.
- An array copies when its values copy, such as integers and
bool, and moves when they move. - Nothing is lost when an operation fails: a value that cannot be added comes back to you in the error.
Ownership describes moves and borrows in full.
Comparing
== and != do not compare text, lists or arrays. Compare their lengths and values with your own code.
Outside this reference
This reference covers these three built-in collections. Key-value maps and other collections, text slices, and indexing text by character are outside it.