> ## Documentation Index
> Fetch the complete documentation index at: https://companyname-a7d5b98e-nft-comparison.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Mutability in Tolk vs tilde functions in FunC

export const Aside = ({type = "note", title = "", icon = "", iconType = "regular", children}) => {
  const asideVariants = ["note", "tip", "caution", "danger"];
  const asideComponents = {
    note: {
      outerStyle: "border-sky-500/20 bg-sky-50/50 dark:border-sky-500/30 dark:bg-sky-500/10",
      innerStyle: "text-sky-900 dark:text-sky-200",
      calloutType: "note",
      icon: <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="w-4 h-4 text-sky-500" aria-label="Note">
          <path fill-rule="evenodd" clip-rule="evenodd" d="M7 1.3C10.14 1.3 12.7 3.86 12.7 7C12.7 10.14 10.14 12.7 7 12.7C5.48908 12.6974 4.0408 12.096 2.97241 11.0276C1.90403 9.9592 1.30264 8.51092 1.3 7C1.3 3.86 3.86 1.3 7 1.3ZM7 0C3.14 0 0 3.14 0 7C0 10.86 3.14 14 7 14C10.86 14 14 10.86 14 7C14 3.14 10.86 0 7 0ZM8 3H6V8H8V3ZM8 9H6V11H8V9Z"></path>
        </svg>
    },
    tip: {
      outerStyle: "border-emerald-500/20 bg-emerald-50/50 dark:border-emerald-500/30 dark:bg-emerald-500/10",
      innerStyle: "text-emerald-900 dark:text-emerald-200",
      calloutType: "tip",
      icon: <svg width="11" height="14" viewBox="0 0 11 14" fill="currentColor" xmlns="http://www.w3.org/2000/svg" className="text-emerald-600 dark:text-emerald-400/80 w-3.5 h-auto" aria-label="Tip">
          <path d="M3.12794 12.4232C3.12794 12.5954 3.1776 12.7634 3.27244 12.907L3.74114 13.6095C3.88471 13.8248 4.21067 14 4.46964 14H6.15606C6.41415 14 6.74017 13.825 6.88373 13.6095L7.3508 12.9073C7.43114 12.7859 7.49705 12.569 7.49705 12.4232L7.50055 11.3513H3.12521L3.12794 12.4232ZM5.31288 0C2.52414 0.00875889 0.5 2.26889 0.5 4.78826C0.5 6.00188 0.949566 7.10829 1.69119 7.95492C2.14321 8.47011 2.84901 9.54727 3.11919 10.4557C3.12005 10.4625 3.12175 10.4698 3.12261 10.4771H7.50342C7.50427 10.4698 7.50598 10.463 7.50684 10.4557C7.77688 9.54727 8.48281 8.47011 8.93484 7.95492C9.67728 7.13181 10.1258 6.02703 10.1258 4.78826C10.1258 2.15486 7.9709 0.000106649 5.31288 0ZM7.94902 7.11267C7.52078 7.60079 6.99082 8.37878 6.6077 9.18794H4.02051C3.63739 8.37878 3.10743 7.60079 2.67947 7.11294C2.11997 6.47551 1.8126 5.63599 1.8126 4.78826C1.8126 3.09829 3.12794 1.31944 5.28827 1.3126C7.2435 1.3126 8.81315 2.88226 8.81315 4.78826C8.81315 5.63599 8.50688 6.47551 7.94902 7.11267ZM4.87534 2.18767C3.66939 2.18767 2.68767 3.16939 2.68767 4.37534C2.68767 4.61719 2.88336 4.81288 3.12521 4.81288C3.36705 4.81288 3.56274 4.61599 3.56274 4.37534C3.56274 3.6515 4.1515 3.06274 4.87534 3.06274C5.11719 3.06274 5.31288 2.86727 5.31288 2.62548C5.31288 2.38369 5.11599 2.18767 4.87534 2.18767Z"></path>
        </svg>
    },
    caution: {
      outerStyle: "border-amber-500/20 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-500/10",
      innerStyle: "text-amber-900 dark:text-amber-200",
      calloutType: "warning",
      icon: <svg className="flex-none w-5 h-5 text-amber-400 dark:text-amber-300/80" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" aria-label="Warning">
          <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
        </svg>
    },
    danger: {
      outerStyle: "border-red-500/20 bg-red-50/50 dark:border-red-500/30 dark:bg-red-500/10",
      innerStyle: "text-red-900 dark:text-red-200",
      calloutType: "danger",
      icon: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" fill="currentColor" className="text-red-600 dark:text-red-400/80 w-4 h-4" aria-label="Danger">
          <path d="M17.1 292c-12.9-22.3-12.9-49.7 0-72L105.4 67.1c12.9-22.3 36.6-36 62.4-36l176.6 0c25.7 0 49.5 13.7 62.4 36L494.9 220c12.9 22.3 12.9 49.7 0 72L406.6 444.9c-12.9 22.3-36.6 36-62.4 36l-176.6 0c-25.7 0-49.5-13.7-62.4-36L17.1 292zm41.6-48c-4.3 7.4-4.3 16.6 0 24l88.3 152.9c4.3 7.4 12.2 12 20.8 12l176.6 0c8.6 0 16.5-4.6 20.8-12L453.4 268c4.3-7.4 4.3-16.6 0-24L365.1 91.1c-4.3-7.4-12.2-12-20.8-12l-176.6 0c-8.6 0-16.5 4.6-20.8 12L58.6 244zM256 128c13.3 0 24 10.7 24 24l0 112c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-112c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"></path>
        </svg>
    }
  };
  let variant = type;
  let gotInvalidVariant = false;
  if (!asideVariants.includes(type)) {
    gotInvalidVariant = true;
    variant = "danger";
  }
  const iconVariants = ["regular", "solid", "light", "thin", "sharp-solid", "duotone", "brands"];
  if (!iconVariants.includes(iconType)) {
    iconType = "regular";
  }
  return <>
      <div className={`callout my-4 px-5 py-4 overflow-hidden rounded-2xl flex gap-3 border ${asideComponents[variant].outerStyle}`} data-callout-type={asideComponents[variant].calloutType}>
        <div className="mt-0.5 w-4" data-component-part="callout-icon">
          {}
          {icon === "" ? asideComponents[variant].icon : <Icon icon={icon} iconType={iconType} size={14} />}
        </div>
        <div className={`text-sm prose min-w-0 w-full ${asideComponents[variant].innerStyle}`} data-component-part="callout-content">
          {gotInvalidVariant ? <p>
              <span className="font-bold">
                Invalid <code>type</code> passed!
              </span>
              <br />
              <span className="font-bold">Received: </span>
              {type}
              <br />
              <span className="font-bold">Expected one of: </span>
              {asideVariants.join(", ")}
            </p> : <>
              {title && <p className="font-bold">{title}</p>}
              {children}
            </>}
        </div>
      </div>
    </>;
};

<Aside>
  No `~` tilde methods in Tolk.
  For example:

  * `cs.loadInt(32)` modifies a slice and returns an integer.
  * `b.storeInt(x, 32)` modifies a builder.
  * `b = b.storeInt()`  also works because the method returns `self`.

  Method chaining works the same as in JavaScript and produces identical Fift instructions, without runtime overhead.
  Custom methods can also be defined.
</Aside>

In FunC, methods can be called as `.method()` or `~method()`.

In Tolk, all methods use a **dot:** `.method()`. A method *may or may not mutate* the object.
Tolk defines a mutability model that generalizes the behavior of the `~` tilde in FunC.
Behavior and semantics differ from FunC.

Tolk method calls are designed to behave similarly to JavaScript:

| FunC                                                                      | Tolk                                                           |
| ------------------------------------------------------------------------- | -------------------------------------------------------------- |
| `int flags = cs~load_uint(32);`                                           | `var flags = cs.loadUint(32);`                                 |
| `(cs, int flags) = cs.load_uint(32);`                                     | `var flags = cs.loadUint(32);`                                 |
| `(slice cs2, int flags) = cs.load_uint(32);`                              | `var cs2 = cs;` `var flags = cs2.loadUint(32);`                |
| `slice data = get_data().begin_parse();` `int flag = data~load_uint(32);` | `val flag = contract.getData().beginParse().loadUint(32);`     |
| `dict~udict_set(...);`                                                    | `dict.set(...);`                                               |
| `b~store_uint(x, 32);`                                                    | `b.storeInt(x, 32);`                                           |
| `b = b.store_int(x, 32);`                                                 | `b.storeInt(x, 32);` // also works  `b = b.storeUint(32);`     |
| `b = b.store_int(x, 32).store_int(y, 32);`                                | `b.storeInt(x, 32).storeInt(y, 32);`  // also works `b = ...;` |

### Value semantics

By default, function arguments in Tolk are **copied by value**. Function calls **do not** modify the original data.

```tolk theme={null}
fun someFn(x: int) {
    x += 1;
}

var origX = 0;
someFn(origX);  // origX remains 0
someFn(10);     // int
```

This also applies to slices, cells, and other types:

```tolk theme={null}
fun readFlags(cs: slice) {
    return cs.loadInt(32);
}

var flags = readFlags(msgBody);  // msgBody is not modified
// msgBody.loadInt(32) reads the same flags
```

### Mutating function parameters

Adding the `mutate` keyword makes a parameter mutable. To prevent unintended modifications, `mutate` must also be specified when calling the function.

```tolk theme={null}
fun increment(mutate x: int) {
    x += 1;
}

// it's correct, simple and straightforward
var origX = 0;
increment(mutate origX);  // origX becomes 1

// these are compiler errors
increment(origX);         // error, unexpected mutation
increment(10);            // error, not lvalue
origX.increment();        // error, not a method, unexpected mutation
val constX = getSome();
increment(mutate constX); // error, it's immutable since `val`
```

This also applies to slices and other types:

```tolk theme={null}
fun readFlags(mutate cs: slice) {
    return cs.loadInt(32);
}

val flags = readFlags(mutate msgBody);
// msgBody.loadInt(32) will read the next integer
```

A function can define multiple mutate parameters:

```tolk theme={null}
fun incrementXY(mutate x: int, mutate y: int, byValue: int) {
    x += byValue;
    y += byValue;
}

incrementXY(mutate origX, mutate origY, 10);   // both += 10
```

<Aside>
  This behavior is similar to passing by reference, but since ref is already used in TON for cells and slices, the keyword `mutate` is used instead.
</Aside>

### Instance methods and self

Methods — unlike global functions `fun f()` — are declared as `fun receiver_type.f()`.
If a method accepts `self`, it is an instance method; otherwise, it is static.

```tolk theme={null}
fun int.assertNotEq(self, throwIfEq: int) {
    if (self == throwIfEq) {
        throw 100;
    }
}

someN.assertNotEq(10);
10.assertNotEq(10);      // also ok, since self is not mutating
```

By default, `self` is immutable. The method cannot modify the object.

```tolk theme={null}
fun slice.readFlags(self) {
    return self.loadInt(32);  // error, modifying immutable variable
}

fun slice.preloadInt32(self) {
    return self.preloadInt(32);  // ok, it's a read-only method
}
```

### Mutating methods with self

Combining `mutate` with `self` defines a method that modifies the object and is called using the dot syntax.

Example:

```tolk theme={null}
fun slice.readFlags(mutate self) {
    return self.loadInt(32);
}

val flags = msgBody.readFlags();

fun int.increment(mutate self) {
    self += 1;
}

var origX = 10;
origX.increment();    // 11
10.increment();       // error, not lvalue

// Method can also mutate multiple arguments:
fun int.incrementWithY(mutate self, mutate y: int, byValue: int) {
    self += byValue;
    y += byValue;
}

origX.incrementWithY(mutate origY, 10);   // both += 10
```

The standard library includes many mutate **mutate self**, such as in tuples and dictionaries.
In FunC, equivalent mutating methods use the tilde `~`.

```tolk theme={null}
@pure
fun tuple.push<X>(mutate self, value: X): void
    asm "TPUSH"

t.push(1);
```

### Returning self for chaining

Returning `self` works as `return self` in Python or `return this` in JavaScript. It makes methods such as `storeInt()` chainable.

```tolk theme={null}
fun builder.storeInt32(mutate self, x: int): self {
    self.storeInt(x, 32);
    return self;

    // this also works as expected (the same Fift code)
    // return self.storeInt(x, 32);
}

var b = beginCell().storeInt(1, 32).storeInt32(2).storeInt(3, 32);
b.storeInt32(4);     // // works without assignment because it mutates b directly
b = b.storeInt32(5); // works with assignment, since also returns
```

The return type must be explicitly declared as `self`. Omitting it causes a compilation error.

### Mutate self in asm functions

The same behavior can also be implemented in `asm` functions.
A mutation in the compiler works as an implicit return and reassignment of `mutate` parameters.

Example:

```tolk theme={null}
// returns (int, void)
fun increment(mutate x: int): void { ... }

// does: (x', _) = increment(x); x = x'
increment(mutate x);

// returns (int, int, (slice, cell))
fun f2(mutate x: int, mutate y: int): (slice, cell) { ... }

// does: (x', y', r) = f2(x, y); x = x'; y = y'; someF(r)
someF(f2(mutate x, mutate y));

// when `self`, it's the same
// does: (cs', r) = loadInt(cs, 32); cs = cs'; flags = r
flags = cs.loadInt(32);
```

Therefore, an `asm` function should place `self'` onto the stack before returning the result:

```tolk theme={null}
// "TPUSH" pops (tuple) and pushes (tuple')
// so, self' = tuple', and return an empty tensor
// `void` is a synonym for an empty tensor
fun tuple.push<X>(mutate self, value: X): void
    asm "TPUSH"

// "LDU" pops (slice) and pushes (int, slice')
// with asm(-> 1 0), we make it (slice', int)
// so, self' = slice', and return int
fun slice.loadMessageFlags(mutate self): int
    asm(-> 1 0) "4 LDU"
```

To return self, specify a return type.
The compiler handles the rest:

```tolk theme={null}
// "STU" pops (int, builder) and pushes (builder')
// with asm(op self), we put arguments to correct order
// so, self' = builder', and return an empty tensor
// but to make it chainable, `self` instead of `void`
fun builder.storeMessageOp(mutate self, op: int): self
    asm(op self) "32 STU"
```

Low-level constructs are rarely needed. Wrappers around existing functions are usually enough.

```tolk theme={null}
// just do it like this, without asm; it's the same effective

fun slice.myLoadMessageFlags(mutate self): int {
    return self.loadUint(4);
}

fun builder.myStoreMessageOp(mutate self, flags: int): self {
    return self.storeUint(32, flags);
}
```
