# Variables (https://docs-kyrm16yq7-ton-core-docs.vercel.app/llms/tolk/syntax/variables/content.md)



* Use `val` for immutable variables and `var` for mutable variables.
* Use `const` or `global` outside functions.

## Declaration [#declaration]

* `val` declares a variable that is assigned exactly once:

  ```tolk
  fun demo() {
      val coeff = 5;
      // cannot change its value, `coeff += 1` is an error
  }
  ```

* `var` declares a variable that can be reassigned:

  ```tolk
  fun demo() {
      var x = 5;
      x += 1;      // now 6
  }
  ```

### Explicit types [#explicit-types]

A variable may declare its type explicitly. If the type is not specified, it is inferred from the initial assignment:

```tolk
fun demo() {
    var x = 5;         // inferred `int`
    x = null;          // error, cannot assign

    var y: int? = 5;   // specified nullable
    y = null;          // ok
}
```

Explicit types also can be used with structures:

```tolk
fun demo() {
    var p1: Point = { x: 10, y: 20 };

    // without an explicit type, use `Point { ... }`
    var p2 = Point { x: 10, y: 20 };
}
```

### Unassigned variables [#unassigned-variables]

A variable may be declared without an initial value, but it must be assigned before its first use:

```tolk
fun demo(mode: int) {
    var result: int;  // not assigned at declaration

    if (mode == MODE_SLOW) {
        result = doSlowCalc();
    } else if (mode == MODE_FAST) {
        result = doFastCalc();
    } else {
        throw ERR_INVALID_MODE;
    }
    return result;   // ok, it's definitely assigned
}
```

### Multiple variables [#multiple-variables]

Declaring multiple variables at once is tensor destructuring:

```tolk
fun demo() {
    var (a, b) = (1, "");

    // with explicit types
    var (c: int, d: slice) = (1, "");
}
```

### Nested scope [#nested-scope]

A block `{ ... }` introduces a nested scope:

```tolk
fun demo() {
    val x = 10;
    if (smth) {
        val x = 50;  // this is a different `x`
    }
    // x is 10
}
```

## Function parameters [#function-parameters]

Function parameters behave the same as local variables. They can be reassigned, but the reassignment does not affect the caller's state:

```tolk
fun analyze(userId: int?) {
    if (userId == null) {
        userId = DEFAULT_ID;
    }
    // ...
}

fun demo() {
    var id = null as int?;
    analyze(id);
    // id remains `null`
}
```

To make updates to `userId` visible in `demo`, declare the parameter with [`mutate`](/llms/languages/tolk/syntax/mutability/content.md): `mutate userId`.

## Constants [#constants]

Global-scope constants are declared with `const` outside functions:

```tolk
const SLEEP_TIME_SEC = 5
```

The right-hand side must be a constant expression: numbers, const literals, compile-time functions, etc.

```tolk
// ok
const FLAG_JANUARY = 1 << 10
const OP_TRANSFER = "transfer".crc32()

// error: not a constant expression
const CUR_TIME = blockchain.now()
```

The type is inferred unless explicitly specified:

```tolk
const MODE_NORMAL: uint32 = 0
```

Constants are not limited to integers:

```tolk
// type `address`
const ADMIN_ADDR = address("UQ...")

// type `coins`
const MINIMAL_COST = grams("0.05")

// even objects with constant fields
const ZERO_POINT: Point = { x: 0, y: 0 }
```

To calculate CRC32 and similar values at compile time, use [`"...".crc32()`](/llms/languages/tolk/types/strings/content.md) and similar compile-time methods.

To group integer constants, use [enums](/llms/languages/tolk/types/enums/content.md).

## Global variables [#global-variables]

Use the `global` keyword to declare variables outside functions:

```tolk
global runtimeCalls: tuple
```

A `global` must have an explicit type and cannot be initialized at the point of declaration. Initialization is done manually at some point in a program. A contract has several entry points, such as `get fun`, `onInternalMessage`, and others.

A `global` must be initialized along the execution path where it is required.

```tolk
global runtimeCalls: tuple

fun execute() {
    runtimeCalls.push("start execute");
    // ...
}

get fun devTrace() {
    runtimeCalls = [];   // initialize
    val result = execute();
    return (result, runtimeCalls);
}
```

In Tolk, avoid globals when possible. Use [auto-serialization](/llms/languages/tolk/features/auto-serialization/content.md) and [`lazy` loading](/llms/languages/tolk/features/lazy-loading/content.md).

<Callout type="caution">
  Use globals with care. Until initialized, a global holds TVM `NULL`, and any invalid access leads to a runtime failure.
</Callout>
