Skip to main content
Tensors represent ordered collections of values and are written in the form (T1, T2, ...). They occupy multiple TVM stack entries sequentially and are serialized in the same order. For example, (int, slice) represents two values following one another. Tensors are anonymous structures and behave identically. Large tensors are impractical — use structures whenever possible.
In many general-purpose languages, syntax (A, B, C, ...) is used for tuples, not tensors, which are a different type. However, in TON, a tuple is a distinct TVM primitive that has its own syntax [a, b, ...] and semantics.For example, a tensor (int, int, int) represents three integers on the stack, whereas a tuple [int, int, int] is a single stack entry that contains three integers within itself.

Component access

Use tensor.{i} to access tensor components by their index:
// v's type is `(int, int, builder)`
var v = (1, 2, beginCell())

// read
v.0 // 1

// write
v.1 = 123 // v is now (1, 123, builder "")
v.2.storeInt(v.0, 16) // v is now (1, 123, builder "0x0001")

// COMPILATION ERROR!
v.100500
This syntax also works for nested tensors:
fun getNested(): (int, (bool, coins)) {
    // ...
}

fun demo() {
    val v = getNested();
    v.1.0 // bool
}

Tensors as anonymous structures

The struct User below and a tensor (int, slice) have identical stack layouts and serialization rules:
struct User {
    id: int
    name: slice
}
Furthermore, obj.{field} is equivalent to tensor.{i}:
struct Storage {
    lastUpdated: int
    owner: User
}

fun demo(s: Storage) {
    s.lastUpdated;       // s.0
    s.owner.id;          // s.1.0
}

Destructuring assignments

The following syntax is valid:
var (i, j) = (10, 20)
This is a 2-component tensor (10, 20) assigned to two variables:
var tensor = (10, 20)
var (i, j) = tensor
Tensors ("abcd", (10, 20)) and ("abcd", 10, 20) are placed identically as three stack entries containing the values "abcd" (as a slice), 10, and 20, respectively. However, Tolk treats (slice, (int, int)) and (slice, int, int) as distinct types.
// This will NOT compile
var (str, i, j) = ("abcd", (10, 20))

// Yet, the following code is correct
var (str, (i, j)) = ("abcd", (10, 20))
A special placeholder _ can be used on the left side to discard a destructured value:
// j = 20, 10 is discarded
var (_, j) = (10, 20)

Empty tensors

Empty tensors are valid values:
val empty = ()
This is analogous to creating an instance of an empty struct.
In some programming languages, an empty value is known as unit, and functions that don’t return a value can be said to “return a unit”. Tolk uses a special type called void for this purpose.The void type is not compatible with empty tensors, despite both indicating the absence of a value.