Skip to main content
Tolk follows value semantics: function arguments are copied by value. There are no pointers or object references. The mutate keyword, used both at declaration and invocation, allows a function to modify the argument.

Value semantics

Function arguments are copied by value: calls do not modify the original data.
This also applies to slices, cells, and other types:

mutate parameter

The mutate keyword makes a parameter mutable. To prevent unintended modifications, mutate must also be specified at the call site.
This also applies to slices and other types:
A function can define multiple mutate parameters:
This behavior is similar to passing by reference, but since ref is already used in TON for cells and slices, the keyword mutate is chosen.

self in methods

Instance methods are declared as fun <receiver>.f(self). By default, self is immutable:

mutate self

mutate self allows modifying the receiver:
Thus, when calling someSlice.readFlags(), the object is mutated. Methods for structures are declared in the same way:
A mutating method can modify another variable:

How does mutate work?

Tolk code is executed by TVM – a stack-based virtual machine. Mutations work by implicitly returning new values through the stack.
Mutating methods work the same:

T.fromSlice(s) does not modify s

Auto-serialization with fromSlice follows the same mutability rules. Passing an argument without mutate never modifies the original variable. In a call f(anyVariable), the variable remains unchanged. If a function needs to modify its argument, the call must explicitly use mutate: f(mutate anyVariable). The same rule applies to AnyStruct.fromSlice(s). The slice is not mutated, and its internal pointer is not shifted. So, calling s.assertEnd() does not check “nothing is left after loading AnyStruct”.
To check that a slice does not contain excess data, no special actions are required, because fromCell and fromSlice automatically ensure the slice ends after reading. For input 0102FF, an exception 9 is thrown. This behavior can be turned off with an option: