Skip to content

Commit

Permalink
feat(docs): empty contract parameters (#2346)
Browse files Browse the repository at this point in the history
  • Loading branch information
novusnota authored Mar 10, 2025
1 parent 1b9c909 commit 4266240
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
1 change: 1 addition & 0 deletions dev-docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Added descriptions for `&&=`, `||=`, `>>=` and `<<=` augmented assignment operators: PR [#2328](https://github.com/tact-lang/tact/pull/2328)
- Added gas best practices page: PR [#2342](https://github.com/tact-lang/tact/pull/2342)
- Documented semantics of empty contract parameters: PR [#2346](https://github.com/tact-lang/tact/pull/2346)

### Release contributors

Expand Down
32 changes: 31 additions & 1 deletion docs/src/content/docs/book/contracts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ contract ContractParameters(

State variables declared in this way have **no** default value. Instead, they get their initial data only when the contract is deployed, which is much cheaper compared to deployments with an extra initialization step in the [`init(){:tact}`](#init-function) function.

The use of contract parameters syntax conflicts with using an [`init(){:tact}`](#init-function) function or declaring persistent state variables via the [contract fields syntax](#variables). Whenever possible, prefer using contract parameters unless you need specific on-chain deployment logic that must be run exactly once, i.e. via the [`init(){:tact}`](#init-function) function.
The use of contract parameters syntax conflicts with using an `init(){:tact}` function or declaring persistent state variables via the [contract fields syntax](#variables). Whenever possible, prefer using contract parameters unless you need specific on-chain deployment logic that must be run exactly once, i.e. via the `init(){:tact}` function.

```tact
contract ParamParamParam(
Expand All @@ -187,6 +187,21 @@ contract ParamParamParam(
}
```

An empty parameter list is still a parameter list, meaning that the contract won't have an implicit or explicit `init(){:tact}` function and will enjoy storage write optimizations. Removing the empty list makes a contract use the delayed initialization with an implicit `init(){:tact}` function.

```tact
contract StillParam() {
// COMPILATION ERROR! init() cannot be used along with contract parameters
init() {}
}
contract LazyInit {
// Everything's ok, and the following init() is redundant because there
// would be an implicit empty init() anyway in the absence of contract parameters.
init() {}
}
```

:::note

To obtain the initial state of the target contract in [internal functions](#internal-functions), [receivers](#receiver-functions), or [getters](#getter-functions), use the [`initOf{:tact}`](/book/expressions#initof) expression.
Expand Down Expand Up @@ -373,6 +388,21 @@ contract ParamParamParam(
}
```

Note that even an empty contract parameter list counts as using [contract parameters syntax](#parameters) and means that the contract won't have any variables in its persistent state. Removing the empty list makes a contract use the delayed initialization with an implicit `init(){:tact}` function.

```tact
contract StillParam() {
// COMPILATION ERROR! init() cannot be used along with contract parameters
init() {}
}
contract LazyInit {
// Everything's ok, and the following init() is redundant because there
// would be an implicit empty init() anyway in the absence of contract parameters.
init() {}
}
```

:::note

To obtain the initial state of the target contract in [internal functions](#internal-functions), [receivers](#receiver-functions), or [getters](#getter-functions), use the [`initOf{:tact}`](/book/expressions#initof) expression.
Expand Down

0 comments on commit 4266240

Please sign in to comment.