FunC reserved words and built-ins
The official smart contract language of TON Blockchain is Tolk. FunC is now a legacy language, with its compiler no longer maintained.
FunC pages will be moved down in the sidebar in mid-April 2026. Here is the preview of a possible future placement, right between "Blockchain foundations" and "Contribute" sections:


Learn how to migrate from FunC to Tolk.
Reserved keywords
FunC reserves the following symbols and words. These cannot be used as identifiers.
Symbols
+ - * /
% ? : ,
; ( ) [
] { } =
_ < > &
| ^ ~ ==
!= <= >= <=>
<< >> ~>> ^>>
~/ ^/ ~% ^%
/% += -= *=
/= ~/= ^/= %=
~%= ^%= <<= >>=
~>>= ^>>= &= |=
^= ->
Words
return var repeat do
while until try catch
if ifnot then else
elseif elseifnot int cell
slice builder cont tuple
type forall extern global
asm impure inline inline_ref
auto_apply method_id operator infix
infixl infixr const #pragma
#include
Built-ins
This section covers extra language constructs that are not part of the core but are still important for functionality. Although they could be implemented in stdlib.fc, keeping them as built-in features allows the FunC optimizer to work more efficiently.
In addition, FunC does not allow the built-in names in this section to be used as identifiers. However, there is an exception: built-ins with non-symbolic names can be used as identifiers for local variables.
Built-ins with symbolic names
_+_ _-_ -_ _*_
_/_ _~/_ _^/_ _%_
_~%_ _^%_ _/%_ _<<_
_>>_ _~>>_ _^>>_ _&_
_|_ _^_ ~_ ^_+=_
^_-=_ ^_*=_ ^_/=_ ^_~/=_
^_^/=_ ^_%=_ ^_~%=_ ^_^%=_
^_<<=_ ^_>>=_ ^_~>>=_ ^_^>>=_
^_&=_ ^_|=_ ^_^=_ _==_
_!=_ _<_ _>_ _<=_
_>=_ _<=>_
Each one of the above names is a function wrapping the corresponding operator.
For example, _+_ can be understood as wrapping the + operator:
int _+_(int a, int b) { return a + b; }These functions are useful when operators need to be passed as arguments to functions, or assigned to variables.
For example, in the following snippet, function apply receives as argument a function f of type (int, int) -> int
and applies it on the arguments 2 and 3:
int apply(((int, int) -> int) f) {
return f(2, 3);
}Then, it is possible to invoke apply by passing _+_:
apply(_+_); ;; Returns 5Attempting to pass the operator + directly does not compile:
apply(+); ;; DOES NOT COMPILEBuilt-ins with non-symbolic names
muldiv muldivr muldivc muldivmod
null? throw throw_if throw_unless
throw_arg throw_arg_if throw_arg_unless load_int
load_uint preload_int preload_uint store_int
store_uint ~store_int ~store_uint load_bits
preload_bits int_at cell_at slice_at
run_method0 run_method1 run_method2 run_method3
divmod
(int, int) divmod(int dividend, int divisor)divmod takes two integers as input and returns the quotient and remainder of their division dividend / divisor.
~divmod
Same as divmod, but allows using modifying notation.
Example:
int a = 10;
int b = 2;
;; "mod" stores the modulo 10 % 2
;; and "a" gets updated with the quotient of 10 / 2
int mod = a~divmod(b);
;; Here, a has value 5
;; mod has value 0
;; b has value 2moddiv
(int, int) moddiv(int dividend, int divisor)moddiv takes two integers as input and returns the remainder and quotient of their division dividend / divisor.
~moddiv
Same as moddiv, but allows using modifying notation.
Example:
int a = 10;
int b = 2;
;; "div" stores the quotient of 10 / 2
;; and "a" gets updated with the modulo 10 % 2
int div = a~moddiv(b);
;; Here, a has value 0
;; div has value 5
;; b has value 2muldiv
int muldiv(int factor1, int factor2, int divisor)muldiv performs a multiply-then-divide operation (factor1 * factor2) / divisor, where / is the division operator.
It uses a 513-bit intermediate result to prevent overflow if the final result fits within 257 bits.
muldivr
int muldivr(int factor1, int factor2, int divisor)muldivr performs a multiply-then-divide operation (factor1 * factor2) ~/ divisor, where ~/ is the rounding division operator.
It uses a 513-bit intermediate result to prevent overflow if the final result fits within 257 bits.
muldivc
int muldivc(int factor1, int factor2, int divisor)muldivc performs a multiply-then-divide operation (factor1 * factor2) ^/ divisor, where ^/ is the ceiling division operator.
It uses a 513-bit intermediate result to prevent overflow if the final result fits within 257 bits.
muldivmod
(int, int) muldivmod(int factor1, int factor2, int divisor)muldivmod performs a multiply-then-divide operation (factor1 * factor2) / divisor, where / is the division operator,
and returns the quotient and remainder of such division. It uses a 513-bit intermediate result to prevent overflow if the final result fits within 257 bits.
true
true is an alias for -1.
false
false is an alias for 0.
nil
nil is an alias for the null value.
Nil
Nil is an alias for the empty tuple [].
null?
forall X -> int null?(X val)null? checks if the given argument is null. Returns 0 if the argument is not null, and -1 otherwise.
For more info, see null values.
throw
() throw(int error)Triggers an exception, which interrupts the execution flow.
throw takes only one argument, the error code. See TVM error codes for details about error codes.
throw_if
() throw_if(int error, int condition)Triggers an exception only if the provided condition is true, i.e., if the condition is -1.
It receives two arguments: the error code, which defines the exception type, and the condition.
See TVM error codes for details about error codes.
throw_unless
() throw_unless(int error, int condition)Triggers an exception only if the provided condition is false, i.e., if the condition is 0.
It receives two arguments: the error code, which defines the exception type, and the condition.
See TVM error codes for details about error codes.
throw_arg
forall X -> () throw_arg(X arg, int error)Triggers an exception, which interrupts the execution flow.
The first argument can be of any type, and it is used to pass extra information about the error. This extra information can be
processed in try..catch statements.
Refer to the try..catch statement page for an example on how to use the first argument.
The second argument is the error code. See TVM error codes for details about error codes.
throw_arg_if
forall X -> () throw_arg_if(X arg, int error, int condition)Triggers an exception only if the provided condition is true, i.e., if the condition is -1.
Similarly to throw_arg, the first argument can be of any type, and it is used to pass extra information about the error. This extra information can be
processed in try..catch statements, in the same way as with throw_arg.
The second argument is the error code. See TVM error codes for details about error codes.
The third argument is the condition to check.
throw_arg_unless
forall X -> () throw_arg_unless(X arg, int error, int condition)Triggers an exception only if the provided condition is false, i.e., if the condition is 0.
Similarly to throw_arg, the first argument can be of any type, and it is used to pass extra information about the error. This extra information can be
processed in try..catch statements, in the same way as with throw_arg.
The second argument is the error code. See TVM error codes for details about error codes.
The third argument is the condition to check.
load_int
(slice, int) load_int(slice s, int len)Reads a signed len-bit integer from slice s. Returns the modified slice and the obtained integer.
load_uint
(slice, int) load_uint(slice s, int len)Reads an unsigned len-bit integer from slice s. Returns the modified slice and the obtained unsigned integer.
preload_int
int preload_int(slice s, int len)Reads a signed len-bit integer from slice s. Returns the obtained integer. This method does not modify slice s.
preload_uint
int preload_uint(slice s, int len)Reads an unsigned len-bit integer from slice s. Returns the obtained unsigned integer. This method does not modify slice s.
store_int
builder store_int(builder b, int x, int len)Stores a signed len-bit integer x in builder b. Returns the modified builder.
store_uint
builder store_uint(builder b, int x, int len)Stores an unsigned len-bit integer x in builder b. Returns the modified builder.
~store_int
(builder, ()) ~store_int(builder b, int x, int len)Same as store_int, but adapted to use modifying notation.
~store_uint
(builder, ()) ~store_uint(builder b, int x, int len)Same as store_uint, but adapted to use modifying notation.
load_bits
(slice, slice) load_bits(slice s, int len)Loads the first len bits from slice s. It returns the modified slice and a slice containing the loaded bits.
preload_bits
slice preload_bits(slice s, int len)Loads the first len bits from slice s. It returns a slice containing the loaded bits. This method does not modify slice s.
int_at
int int_at(tuple t, int index)Returns the element at index index in tuple t, casted as an integer.
It is responsibility of the programmer to check that the returned element is actually an integer.
cell_at
cell cell_at(tuple t, int index)Returns the element at index index in tuple t, casted as a cell.
It is responsibility of the programmer to check that the returned element is actually a cell.
slice_at
slice slice_at(tuple t, int index)Returns the element at index index in tuple t, casted as a slice.
It is responsibility of the programmer to check that the returned element is actually a slice.
tuple_at
tuple tuple_at(tuple t, int index)Returns the element at index index in tuple t, casted as a tuple.
It is responsibility of the programmer to check that the returned element is actually a tuple.
at
forall X -> X at(tuple t, int index)Returns the element at index index in tuple t. The returned element can be of any type.
touch
forall X -> X touch(X v)Moves v to the top of the stack. It returns the argument v.
~touch
forall X -> (X, ()) ~touch(X v)~touch is identical to touch, but adapted to use modifying notation.
touch2
forall X, Y -> (X, Y) touch2((X, Y) t)Moves the components of the tensor t to the top of the stack; first component with type X and then component with type Y. It returns the argument tensor t.
~touch2
forall X, Y -> ((X, Y), ()) ~touch2((X, Y) t)~touch2 is identical to touch2, but adapted to use modifying notation.
~dump
forall X -> (X, ()) ~dump(X value)Outputs value value to the debug log. It returns the argument value and the unit value ().
Modifying notation can be used on this function.
In case value is a slice containing ASCII characters, it is preferable to use ~strdump if the intention is
to print the ASCII string in the debug log. Otherwise, ~dump will print the slice's contents as bits.
~strdump
forall X -> (X, ()) ~strdump(X s)Outputs to the debug log the ASCII string encoded in slice s. It returns the argument s and the unit value ().
Modifying notation can be used on this function.
If the argument s is not a slice containing ASCII characters, the debug log will show an error.
run_method0
() run_method0 (int method_id)Executes the 0 argument function with ID method_id. The function with ID method_id must have a signature of the form:
() some_function()which receives 0 arguments and returns nothing.
The run_method0 is useful for dynamically executing methods at run-time.
For example, receiving the method ID to execute in the incoming internal message.
Recall that method ids can be explicitly set when declaring functions using the method_id specifier:
() test() method_id(1234)So that later, it can be invoked as:
run_method0(1234); ;; executes function testThe FunC compiler does not check that the function to execute in run_method0 has the correct number of arguments and
that it returns (). This is responsibility of the programmer.
run_method1
forall X -> () run_method1 (int method_id, X arg1)Executes the 1 argument function with ID method_id, and passes arg1 as argument to the function.
The function with ID method_id must have a signature of the form:
() some_function(T a1)which receives 1 argument and returns nothing. Type T must coincide with the type of the argument arg1 provided in run_method1.
For example, under the assumption that 1234 is the ID of function test, invoking:
;; The argument "a" is a slice containing the ASCII character 'a'
run_method1(1234, "a");requires that test has the signature:
() test(slice s)As with run_method0, function run_method1 is useful for dynamically executing 1 argument methods at run-time.
The FunC compiler does not check that the function to execute in run_method1 has the correct number of arguments,
that it returns (), and that the types of arguments in run_method1 and the function to execute coincide. This is responsibility of the programmer.
run_method2
forall X, Y -> () run_method2 (int method_id, X arg1, Y arg2)Executes the 2 argument function with ID method_id. The function with ID method_id must have a signature of the form:
() some_function(T1 a1, T2 a2)which receives 2 arguments and returns nothing. Type T1 must coincide with the type of the argument arg1 provided in run_method2,
and similarly for type T2.
The same observations and warnings apply as with run_method1.
run_method3
forall X, Y, Z -> () run_method3 (int method_id, X arg1, Y arg2, Z arg3)Executes the 3 argument function with ID method_id. The function with ID method_id must have a signature of the form:
() some_function(T1 a1, T2 a2, T3 a3)which receives 3 arguments and returns nothing. Type T1 must coincide with the type of the argument arg1 provided in run_method3,
and similarly for types T2 and T3.
The same observations and warnings apply as with run_method1.
Last updated on