Skip to content

Expressions

Every operator in Tact forms an expression, but there’s much more to uncover, as Tact offers a wide range of expressive options to choose from.

Literals

Literals represent values in Tact. These are fixed values—not variables—that you literally provide in your code. All literals in Tact are expressions themselves.

You can also call extension functions defined on certain primitive types directly on their corresponding literal values:

// Calling toString() defined for Int on an integer literal:
42.toString();
// Calling asComment() defined for String on a string literal:
"Tact is awesome!".asComment();

Integer literals

Integer literals can be written in decimal (base 1010), hexadecimal (base 1616), octal (base 88), and binary (base 22) notations:

  • A decimal integer literal is a sequence of digits (09\mathrm{0 - 9}).

  • A leading 0x\mathrm{0x} (or 0X\mathrm{0X}) indicates a hexadecimal integer literal. They can include digits (09\mathrm{0 - 9}) and the letters af\mathrm{a - f} and AF\mathrm{A - F}. Note that the case of a character does not change its value. Therefore, 0xa\mathrm{0xa} = 0xA\mathrm{0xA} = 10 and 0xf\mathrm{0xf} = 0xF\mathrm{0xF} = 15.

  • A leading 0o\mathrm{0o} (or 0O\mathrm{0O}) indicates an octal integer literal. They can include only the digits 07\mathrm{0 - 7}.

  • A leading 0b\mathrm{0b} (or 0B\mathrm{0B}) indicates a binary integer literal. They can include only the digits 00 and 11.

Some examples of integer literals:

// decimal, base 10:
0, 42, 1_000, 020
// hexadecimal, base 16:
0xABC, 0xF, 0x0011
// octal, base 8:
0o777, 0o001
// binary, base 2:
0b01111001_01101111_01110101_00100000_01100001_01110010_01100101_00100000_01100001_01110111_01100101_01110011_01101111_01101101_01100101

Read more about integers and the Int type on the dedicated page: Integers.

Boolean literals

The Bool type has only two literal values: true and false.

true == true;
true != false;

Read more about booleans and the Bool type in the dedicated chapter: Booleans.

String literals

A string literal is zero or more characters enclosed in double (") quotation marks. All string literals are objects of the String type.

"foo";
"1234";

Tact strings support a range of escape sequences starting with a backslash \\ character:

  • \\ — literal backslash
  • \" — double quote
  • \n — newline
  • \r — carriage return
  • \t — tab
  • \v — vertical tab
  • \b — backspace
  • \f — form feed
  • \x00 through \xFFcode point, must be exactly two hex digits long
  • \u0000 through \uFFFFUnicode code point, must be exactly four hex digits long
  • \u{0} through \u{FFFFFF}Unicode code point, can be from 1 to 6 hex digits long
// \\
"escape \\ if \\ you \\ can \\";
// \"
"this \"literally\" works";
// \n
"line \n another line";
// \r
"Shutters \r Like \r This \r One";
// \t
"spacing \t granted!";
// \v
"those \v words \v are \v aligned";
// \b
"rm\b\bcreate!";
// \f
"form \f feed";
// \x00 - \xFF
"this \x22literally\x22 works"; // \x22 represents a double quote
// \u0000 - \uFFFF
"danger, \u26A1 high voltage \u26A1"; // \u26A1 represents the ⚡ emoji
// \u{0} - \u{FFFFFF}
"\u{1F602} LOL \u{1F602}"; // \u{1F602} represents the 😂 emoji

null literal

The null value is written with a null literal. It is not an identifier and does not refer to any object. It is also not an instance of a primitive type. Instead, null represents a lack of identification and the intentional absence of any value.

let var: Int? = null; // variable which can hold a null value
var = 42;
if (var != null) {
var!! + var!!;
}

Read more about working with null on the dedicated page: Optionals.

Identifiers

An identifier is a sequence of characters in the code that identifies a variable, constant, map, a function, as well as a Struct, Message, contract, trait, or their fields and methods. Identifiers are case-sensitive and not quoted.

In Tact, identifiers may contain Latin lowercase letters a-z, Latin uppercase letters A-Z, underscores _, and digits 09\mathrm{0 - 9}, but may not start with a digit. No other symbols are allowed, and Unicode identifiers are prohibited.

Note that identifiers for primitive types start with an uppercase letter. User-defined composite types, such as Structs and Messages, must also be capitalized.

Instantiation

You can create instances of the following types:

struct StExample {
fieldInit: Int = 1;
fieldUninit: Int;
}
fun example() {
// Instance with default value of fieldInit
StExample{ fieldUninit: 2 };
// Instance with both fields set
StExample{
fieldInit: 0,
fieldUninit: 2, // trailing comma is allowed
};
}

Field access

You can directly access fields of the following types:

struct StExample {
fieldInit: Int = 1;
fieldUninit: Int;
}
fun example(): Int {
let struct: StExample = StExample{ fieldUninit: 2 }; // instantiation
struct.fieldInit; // access a field
return struct.fieldUninit; // return field value from the function
}

Extension function call

Extension functions are defined only on specific types. They can be called similarly to method calls in many other languages:

42.toString(); // toString() is a stdlib function that is defined on Int type

Static function call

A global static function or an internal function of a contract can be called from anywhere in the function body:

contract ExampleContract {
receive() {
now(); // now() is a static function of stdlib
let expiration: Int = now() + 1000; // operation and variable declaration
expiration = self.answerQuestion(); // internal function
}
fun answerQuestion(): Int {
return 42;
}
}

initOf

Gas-expensive

The expression initOf computes the initial state, i.e., StateInit, of a contract:

// argument values for the init() function of the contract
// ↓ ↓
initOf ExampleContract(42, 100); // returns a Struct StateInit{}
// ---------------
// ↑
// name of the contract
// ↓
// ---------------
initOf ExampleContract(
42, // first argument
100, // second argument; a trailing comma is allowed
);

The StateInit is a Struct consisting of the following fields:

FieldTypeDescription
codeCellThe initial code of the contract (compiled bitcode)
dataCellThe initial data of the contract (parameters of the init() function or contract parameters)

codeOf

Gas-expensive Available since Tact 1.6

The expression codeOf returns a Cell containing the code of a contract:

codeOf ExampleContract; // a Cell with ExampleContract code
// ---------------
// ↑
// name of the contract

If codeOf is used for the current contract, its result is equivalent to calling myCode().

contract ExampleContract {
receive() {
myCode() == codeOf ExampleContract; // true
}
}

If you only need the code of a given contract and not its StateInit, prefer using codeOf ContractName over initOf ContractName(param1, param2, ...) to significantly reduce gas usage.