> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ton.org/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.ton.org/feedback

```json
{
  "path": "/tolk/from-func/tolk-vs-func",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Tolk vs FunC

FunC is the first high-level language for TON smart contracts. Legacy FunC codebases exist, but the compiler is no longer maintained.
Tolk is the primary and only actively supported language in the TON ecosystem.

## Migrating from FunC to Tolk

1. Review the list of [differences](/languages/tolk/from-func/tolk-vs-func#key-differences).
2. See the [Tolk contract examples](/languages/tolk/examples) page.
3. Use the [FunC-to-Tolk converter](/languages/tolk/from-func/converter) to migrate existing projects.

## Gas benchmarks

The [`tolk-bench` repository](https://github.com/ton-blockchain/tolk-bench) compares FunC and Tolk across several TEP contracts. See the [Tolk contract examples](/languages/tolk/examples) page for selected cases.

Across all measured metrics, Tolk reduces gas consumption by 30–50% compared to FunC. This reduction is primarily due to differences in language design.

## Common characteristics

* Both languages compile to Fift assembler.
* Both languages run on [TVM](/tvm/overview) after compilation to bitcode.
* Both languages are supported by [IDE plugins](/contract-dev/ide/overview).
* Both languages are available in [Blueprint](/contract-dev/blueprint/overview) and other client-side tooling.
* Both support command-line usage.

## Key differences

The differences between Tolk and FunC are primarily in language design rather than syntax.

### Basic syntax

* FunC resembles C, the name stands for "functional C".
* [Tolk resembles](/languages/tolk/basic-syntax) TypeScript, Rust, and Kotlin.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun sum(a: int, b: int): int {
    return a + b;
}
```

### Structures

* FunC uses unnamed tensors such as `(int, slice, int, int)`.
* Tolk uses named [structures](/languages/tolk/syntax/structures-fields) with the same runtime efficiency.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
struct Demo {
    previousValue: int256
    ownerAddress: address
    effectsCount: uint32
    totalAmount: coins
}
```

### Automatic serialization

* FunC requires manual bit-level serialization using builders and slices.
* Tolk derives [serialization](/languages/tolk/features/auto-serialization) from `struct` using `toCell` and `fromCell`.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
struct Point {
    x: int8
    y: int8
}

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

    // makes a cell containing "0A14" (hex)
    var c = value.toCell();
    // back to { x: 10, y: 20 }
    var p = Point.fromCell(c);
}
```

All [integer types](/languages/tolk/types/numbers) such as `int8`, `uint64`, and `coins` are TVM integers.

### Lazy loading

* FunC requires manual control over preloads and skips for optimization.
* Tolk uses the [`lazy` keyword](/languages/tolk/features/lazy-loading) to load only accessed fields.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
get fun publicKey() {
    val st = lazy Storage.load();
    // <-- here "skip 65 bits, preload uint256" is inserted
    return st.publicKey
}
```

### Boolean type

* FunC represents only integers: `-1` for true, `0` for false; `ifnot`.
* Tolk provides a [`bool` type](/languages/tolk/types/booleans) and logical operators `&&`, `||`, and `!`.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
if (trustInput || validate(input)) {
    // ...
}
```

### Address type

* FunC represents only slices; bits comparison and parsing.
* Tolk provides a [`address` type](/languages/tolk/types/address) with methods and the `==` operator.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
if (in.senderAddress == storage.ownerAddress) {
    val workchain = storage.ownerAddress.getWorkchain();
    // ...
}
```

### Null safety

* FunC allows any variable to hold `null`, which may lead to runtime errors.
* Tolk provides [nullable types](/languages/tolk/types/nullable) `T?`, null safety, and smart casts.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun checkWithOptional(a: int, b: int?): bool {
    if (b == null) {
        return checkSingle(a);
    }
    return b >= 0 && checkDouble(a, b);
}
```

### Type system features

* FunC provides several types that expose TVM primitives.
* Tolk provides [a type system](/languages/tolk/types/list-of-types), including unions, generics, and enums.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
struct Container<T> {
    element: T?
}

struct Nothing

type Wrapper<T> = Nothing | Container<T>
```

### Methods for all types

* FunC provides functions in the global scope only.
* Tolk provides both [functions and methods](/languages/tolk/syntax/functions-methods), applicable to structures and primitives.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
// no `self` — static method
fun Point.createZero(): Point {
    return { x: 0, y: 0 }
}

// has `self` — instance method
fun Point.sumCoords(self) {
    return self.x + self.y
}

// even for primitives: cells, integers, tuples, etc.
fun tuple.isEmpty(self) {
    return self.size() == 0
}
```

### No `impure` keyword

* In FunC, if `impure` is omitted, a function call may be dropped.
* In Tolk, user function calls are not removed by the compiler.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun validate(input: SomeStruct) {
    // ...
}
```

### No `~` tilde methods

* FunC distinguishes between `x~f()` and `x.f()`.
* Tolk uses a dot `.` syntax for method calls.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
val delta = someSlice.loadUint(32);   // mutates someSlice
val owner = someSlice.loadAddress();
```

### Native maps over TVM dictionaries

* FunC uses dictionaries, for example `m~idict_set_builder(1,32,begin_cell().store_uint(10,32))`.
* Tolk provides native [maps](/languages/tolk/types/maps), for example `m.set(1, 10)`.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
var m: map<int8, int32> = [];
m.set(1, 10);
m.addIfNotExists(2, -20);
m.delete(2);   // now: [ 1 => 10 ]
```

### Message handling

* FunC defines `() recv_internal(4 params)` and parses a message cell.
* Tolk provides [`onInternalMessage(in)`](/languages/tolk/features/message-handling) and use `in.senderAddress`, etc.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun onInternalMessage(in: InMessage) {
    // internal non-bounced messages arrive here
    in.senderAddress;
    in.originalForwardFee;
    // and other fields
}

fun onBouncedMessage(in: InMessageBounced) {
    // bounced messages arrive here
}
```

### Message routing

* FunC routes incoming messages using `if-else` checks on the `opcode`, for example `if (op == OP_TRANSFER)`.
* Tolk routes messages using union types and [pattern matching](/languages/tolk/syntax/pattern-matching).

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
type MyMessage =
    | CounterIncBy
    | CounterReset
    // ...

fun onInternalMessage(in: InMessage) {
    val msg = lazy MyMessage.fromSlice(in.body);
    match (msg) {
        CounterIncBy => {
            // ...
        }
        CounterReset => {
            // ...
        }
        // ...
    }
}
```

### Empty messages handling

* FunC checks for empty message bodies using `if (slice_empty?(...))` at the beginning of `recv_internal()`.
* Tolk handles empty or unknown messages using `else` in a [`lazy` matching](/languages/tolk/features/lazy-loading#lazy-matching).

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun onInternalMessage(in: InMessage) {
    val msg = lazy MyMessage.fromSlice(in.body);
    match (msg) {
        CounterReset => { /* ... */ }
        // ... handle all variants of the union

        else => {
            // for example: ignore empty messages
            if (in.body.isEmpty()) {
                return
            }
            throw 0xFFFF
        }
    }
}
```

### Message composition

* FunC requires manual bit-level message construction, for example `store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)`.
* Tolk provides [`createMessage`](/languages/tolk/features/message-sending), which automatically chooses between inline body and body reference.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
val reply = createMessage({
    bounce: BounceMode.NoBounce,
    value: ton("0.05"),
    dest: senderAddress,
    body: RequestedInfo { ... }
});
reply.send(SEND_MODE_REGULAR);
```

### Deployment and `StateInit`

* FunC requires manual packing of contract code and data according to TL-B.
* Tolk uses `createMessage` to attach `StateInit` and compute the destination automatically.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
val deployMsg = createMessage({
    // address auto-calculated, code+data auto-attached
    dest: {
        stateInit: {
            code: contractCodeCell,
            data: emptyStorage.toCell(),
        },
        // optionally control workchains and sharding
    }
});
```

### Identifier syntax

* FunC allows arbitrary symbols in identifiers, for example `var 2+2 = ...`.
* Tolk allows only [alphanumeric identifiers](/languages/tolk/syntax/variables), for example  `2+2` is `4`.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
const OP_INCREASE = 0x12345678
```

### Automatic inlining of small functions

* In FunC, prefer larger functions for reduced gas consumption.
* In Tolk, the compiler auto-inlines functions without additional gas cost.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
fun int.zero() {
    return 0
}

fun int.inc(mutate self, byValue: int = 1): self {
    self += byValue;
    return self;
}

fun main() {
    return int.zero().inc().inc()
}
```

Is reduced to `return 2` in assembler:

```fift theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
main() PROC:<{
    2 PUSHINT
}>
```

In FunC, `inline` modifier operates at the Fift level and may introduce extra stack permutations. In Tolk, inlining is performed at the compiler level and is combined with [constant folding](/languages/tolk/features/compiler-optimizations).

### Merging consecutive `builder.storeUint`

* FunC manually combines constant stores into `b.storeUint(0x18,6)`.
* Tolk merges `b.storeUint(...).storeUint(...)` if constant.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
b.storeUint(0, 1)
 .storeUint(1, 1)
 .storeUint(1, 1)
 .storeUint(0, 1)
 .storeUint(0, 2)
```

Translated to:

```fift theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
b{011000} STSLICECONST
```

### Standard library redesigned

There are [differences between standard libraries](/languages/tolk/from-func/stdlib-fc). For example, functions from `stdlib.fc` started having descriptive names:

|         FunC         |                Tolk               |
| :------------------: | :-------------------------------: |
|      `cur_lt()`      |     `blockchain.logicalTime()`    |
|       `car(l)`       |          `list.getHead()`         |
| `raw_reserve(coins)` | `reserveToncoinsOnBalance(coins)` |
|      `~dump(x)`      |          `debug.print(x)`         |

Many global-scope functions became methods for primitives:

|            FunC            |         Tolk        |
| :------------------------: | :-----------------: |
|      `s.slice_hash()`      |      `s.hash()`     |
|  `equal_slices_bits(a, b)` |   `a.bitsEqual(b)`  |
|       `t.tuple_len()`      |      `t.size()`     |
| `t~tpush(triple(x, y, z))` | `t.push([x, y, z])` |

String postfixes like `"..."c` became compile-time methods on strings:

|   FunC   |         Tolk         |
| :------: | :------------------: |
| `"..."c` |    `"...".crc32()`   |
| `"..."H` |   `"...".sha256()`   |
| `"..."h` |  `"...".sha256_32()` |
| `"..."s` | `"...".hexToSlice()` |
| `"..."u` |  `"...".toBase256()` |
| `"..."a` |   `address("...")`   |

### Assembler functions

Although Tolk is a high-level language, it exposes [low-level capabilities](/languages/tolk/features/asm-functions). Code may still be written in a FunC-style with manual builders and slices, and TVM instructions are supported.

```tolk theme={"theme":{"light":"github-light-default","dark":"dark-plus"},"languages":{"custom":["/resources/grammars/tolk.tmLanguage.json","/resources/grammars/tlb.tmLanguage.json","/resources/grammars/fift.tmLanguage.json","/resources/grammars/tasm.tmLanguage.json","/resources/grammars/func.tmLanguage.json"]}}
@pure
fun incThenNegate(v: int): int
    asm "INC" "NEGATE"
```
