Skip to content
This repository was archived by the owner on Dec 12, 2024. It is now read-only.

Commit 2ca66a0

Browse files
authoredMar 25, 2024
chore: Split composite-types into standalone pages (#137)
* Added small references to `types` * Corrected all the links * Added a redirect * "Structs and Messages", "Maps" and "Optionals" -- now became standalone pages
1 parent f908d55 commit 2ca66a0

11 files changed

+169
-117
lines changed
 

‎pages/book/_meta.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@ export default {
99
},
1010
types: 'Type system overview',
1111
integers: 'Integers',
12+
maps: 'Maps',
13+
'structs-and-messages': 'Structs and Messages',
14+
optionals: 'Optionals',
15+
// <- a place for https://github.com/tact-lang/tact-docs/issues/115 + brief info on comments
16+
'-- 2': {
17+
type: 'separator',
18+
title: 'Expressiveness',
19+
},
1220
operators: 'Operators',
1321
expressions: 'Expressions',
1422
statements: 'Statements',
1523
constants: 'Constants',
1624
functions: 'Functions',
17-
'composite-types': 'Composite types',
18-
// <- a place for https://github.com/tact-lang/tact-docs/issues/115
19-
'-- 2': {
25+
'-- 3': {
2026
type: 'separator',
2127
title: 'Communication',
2228
},
@@ -29,7 +35,7 @@ export default {
2935
lifecycle: 'Message lifecycle',
3036
send: 'Sending messages',
3137
'message-mode': 'Message mode',
32-
'-- 3': {
38+
'-- 4': {
3339
type: 'separator',
3440
title: 'Going places',
3541
},

‎pages/book/cookbook.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ if (first == null) {
137137
<Callout>
138138

139139
**Useful links:**\
140-
[`map<k, v>{:tact}` type in the Book](/book/types#maps)
140+
[`map<k, v>{:tact}` type in the Book](/book/maps)
141141

142142
</Callout>
143143

‎pages/book/expressions.mdx

+5-5
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,15 @@ if (var != null) {
9292
}
9393
```
9494

95-
Read more about working with `null{:tact}` in the dedicated chapter: [Optionals](/book/composite-types#optionals).
95+
Read more about working with `null{:tact}` on the dedicated page: [Optionals](/book/optionals).
9696

9797
## Identifiers
9898

99-
An identifier is a sequence of characters in the code that _identifies_ a [variable](/book/statements#let), [constant](/book/constants), [map](/book/types#maps) and a [function](/book/functions), as well as a [Struct][s], [Message][m], [contract](/book/types#contract), [trait](/book/types#trait), or their fields and methods. Identifiers are case-sensitive and not quoted.
99+
An identifier is a sequence of characters in the code that _identifies_ a [variable](/book/statements#let), [constant](/book/constants), [map](/book/maps) and a [function](/book/functions), as well as a [Struct][s], [Message][m], [contract](/book/types#contract), [trait](/book/types#trait), or their fields and methods. Identifiers are case-sensitive and not quoted.
100100

101101
In Tact, identifiers can contain latin lowercase letters (`a-z`), latin uppercase letters (`A-Z`), underscores (`_`) and digits ($\mathrm{0 - 9}$), but may not start with a digit. An identifier differs from a [string](#string-literals) in that a string is data, while an identifier is part of the code.
102102

103-
Note, that when identifiers for [primitive types][p] start with an uppercase letter. Used-defined [composite types](/book/composite-types), such as [Structs][s] and [Messages][m] also must be capitalized.
103+
Note, that when identifiers for [primitive types][p] start with an uppercase letter. Used-defined [composite types](/book/types#composite-types), such as [Structs][s] and [Messages][m] also must be capitalized.
104104

105105
## Instantiation
106106

@@ -189,5 +189,5 @@ Field | Type | Description
189189
`data` | [`Cell{:tact}`][p] | initial data of the contract (arguments of `init(){:tact}` function of the contract)
190190

191191
[p]: /book/types#primitive-types
192-
[s]: /book/composite-types#structs
193-
[m]: /book/composite-types#messages
192+
[s]: /book/structs-and-messages#structs
193+
[m]: /book/structs-and-messages#messages

‎pages/book/func.mdx

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ All rules about copying variables are the same. One of the big differences is th
1010

1111
## Convert serialization
1212

13-
Serialization of [Structs](/book/composite-types#structs) and [Messages](/book/composite-types#messages) in Tact is automatic, unlike FunC where you need to define serialization logic manually.
13+
Serialization of [Structs](/book/structs-and-messages#structs) and [Messages](/book/structs-and-messages#messages) in Tact is automatic, unlike FunC where you need to define serialization logic manually.
1414

1515
Tact's auto-layout algorithm is greedy. This means that it takes the next variable, calculates its size, and tries to fit it into a current cell. If it doesn't fit, it creates a new cell and continues. All inner structs for auto-layout are flattened before allocation.
1616

@@ -174,7 +174,7 @@ get fun seqno(): Int {
174174

175175
In FunC there is a difference between tensor type `(int, int){:func}` and `(int, (int)){:func}`, but for TVM there are no differences, they all represent a stack of two integers.
176176

177-
To convert the tensor that returned from a FunC `get`-method, you need to define a [Struct](/book/composite-types#structs) that has the same field types as the tensor and in the same order.
177+
To convert the tensor that returned from a FunC `get`-method, you need to define a [Struct](/book/structs-and-messages#structs) that has the same field types as the tensor and in the same order.
178178

179179
The following code in FunC:
180180

@@ -230,7 +230,7 @@ contract StatefulContract {
230230

231231
### Mixed tuple and tensor return types
232232

233-
When some of the tensors are a tuple, you need to define a struct as in previous steps and the tuple one must be defined as a separate [Struct](/book/composite-types#structs).
233+
When some of the tensors are a tuple, you need to define a struct as in previous steps and the tuple one must be defined as a separate [Struct](/book/structs-and-messages#structs).
234234

235235
The following code in FunC:
236236

@@ -262,7 +262,7 @@ contract StatefulContract {
262262

263263
### Arguments mapping
264264

265-
Conversion of `get`-methods arguments is straightforward. Each argument is mapped _as-is_ to FunC one, and each tuple is mapped to a [Struct](/book/composite-types#structs).
265+
Conversion of `get`-methods arguments is straightforward. Each argument is mapped _as-is_ to FunC one, and each tuple is mapped to a [Struct](/book/structs-and-messages#structs).
266266

267267
The following code in FunC:
268268

‎pages/book/integers.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ contract SerializationExample {
6767
}
6868
```
6969

70-
Integer serialization is also available for the fields of [Structs](/book/composite-types#structs) and [Messages](/book/composite-types#structs), as well as in key/value types of [maps](/book/types#maps):
70+
Integer serialization is also available for the fields of [Structs](/book/structs-and-messages#structs) and [Messages](/book/structs-and-messages#messages), as well as in key/value types of [maps](/book/maps):
7171

7272
```tact
7373
struct StSerialization {

‎pages/book/maps.mdx

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Maps
2+
3+
import { Callout } from 'nextra/components'
4+
5+
The type `map<k, v>{:tact}` is used as a way to associate keys of type `k` with corresponding values of type `v`.
6+
7+
Possible key types:
8+
9+
* [`Int{:tact}`][ints]
10+
* `Address{:tact}`
11+
12+
Possible value types:
13+
14+
* [`Int{:tact}`][ints]
15+
* [`Bool{:tact}`](/book/types#booleans)
16+
* `Cell{:tact}`
17+
* `Address{:tact}`
18+
* [Struct](/book/structs-and-messages#structs)
19+
* [Message](/book/structs-and-messages#messages)
20+
21+
For example, `map<Int, Int>{:tact}` uses [`Int{:tact}`][ints] type for its keys and values:
22+
23+
```tact
24+
struct IntToInt {
25+
counters: map<Int, Int>;
26+
}
27+
```
28+
29+
Additionally, maps allow [integer serialization](/book/integers#serialization-types) of their keys, values or both to [preserve space and reduce storage costs](/book/integers#serialization):
30+
31+
```tact
32+
struct SerializedMapInside {
33+
countersButCompact: map<Int as uint8, Int as uint8>;
34+
}
35+
```
36+
37+
<Callout>
38+
39+
Read about other serialization options: [Compatibility with FunC](/book/func#convert-serialization)
40+
41+
</Callout>
42+
43+
[ints]: /book/integers

‎pages/book/operators.mdx

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This page lists all the operators in Tact in decreasing order of their [preceden
88

99
<Callout>
1010

11-
Note, that there are no implicit type conversions in Tact, so operators can't be used to, say, add values of different type or compare them in terms of equality without explicitly casting to the same type. That's done with certain functions from the standard library. See [`Int.toString(){:tact}`](https://docs.tact-lang.org/language/ref/strings#inttostring) for an example of such function.
11+
Note, that there are no implicit type conversions in Tact, so operators can't be used to, say, add values of different type or compare them in terms of equality without explicitly casting to the same type. That's done with certain functions from the standard library. See [`Int.toString(){:tact}`](/language/ref/strings#inttostring) for an example of such function.
1212

1313
</Callout>
1414

@@ -51,7 +51,7 @@ Unary double-exclamation mark (_non-null assertion_) operator `!!{:tact}` is a p
5151

5252
<Callout>
5353

54-
Read more about optional variables and fields here: [Book→Composite Types](https://docs.tact-lang.org/book/composite-types#optionals)
54+
Read more about optional variables and fields here: [Optionals](/book/optionals)
5555

5656
</Callout>
5757

@@ -135,7 +135,7 @@ two % 1; // 1
135135
-1 % -5; // -1
136136
```
137137

138-
The simplest way to avoid confusion between the two is to prefer using positive values via [`abs(x: Int){:tact}`](https://docs.tact-lang.org/language/ref/math#abs):
138+
The simplest way to avoid confusion between the two is to prefer using positive values via [`abs(x: Int){:tact}`](/language/ref/math#abs):
139139

140140
```tact
141141
abs(-1) % abs(-5); // 1
@@ -297,7 +297,7 @@ Can be applied to values of following types:
297297
* [`Cell{:tact}`](/book/types#primitive-types), implicitly compares via `.hash(){:tact}`
298298
* [`Slice{:tact}`](/book/types#primitive-types), implicitly compares via `.hash(){:tact}`
299299
* [`String{:tact}`](/book/types#primitive-types)
300-
* [`map<k, v>{:tact}`](/book/types#maps), but only if their key and value types are identical
300+
* [`map<k, v>{:tact}`](/book/maps), but only if their key and value types are identical
301301

302302
```tact
303303
// Int:
@@ -344,7 +344,7 @@ Can be applied to values of following types:
344344
* [`Cell{:tact}`](/book/types#primitive-types), implicitly compares via `.hash(){:tact}`
345345
* [`Slice{:tact}`](/book/types#primitive-types), implicitly compares via `.hash(){:tact}`
346346
* [`String{:tact}`](/book/types#primitive-types)
347-
* [`map<k, v>{:tact}`](/book/types#maps), but only if their key and value types are identical
347+
* [`map<k, v>{:tact}`](/book/maps), but only if their key and value types are identical
348348

349349
```tact
350350
// Int:
@@ -480,7 +480,7 @@ true ? (false ? 1 : 2) : 3; // 2
480480

481481
## Assignment, `=` [#assignment]
482482

483-
Assignment operator `={:tact}` is used to assign a value to a variable, or to a property of a [Message](/book/composite-types#messages) or a [Struct](/book/composite-types#structs). The assignent is a statement and it doesn't return a value.
483+
Assignment operator `={:tact}` is used to assign a value to a variable, or to a property of a [Message](/book/structs-and-messages#messages) or a [Struct](/book/structs-and-messages#structs). The assignment is a statement and it doesn't return a value.
484484

485485
```tact
486486
let someVar: Int = 5; // assignment operator = is used here...

‎pages/book/optionals.mdx

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Optionals
2+
3+
import { Callout } from 'nextra/components'
4+
5+
As it was mentioned in [type system overview](/book/types#optionals), all [primitive types](/book/types#primitive-types), [Structs](/book/structs-and-messages#structs) and [Messages](/book/structs-and-messages#messages) could be nullable. That is, they don't necessarily hold any value, aside from `null{:tact}` — a special value, which represents the intentional absence of any other value.
6+
7+
[Variables](/book/statements#let) or fields of [Structs](/book/structs-and-messages#structs) and [Messages](/book/structs-and-messages#messages) that can hold `null{:tact}` are called "optionals". They're useful to reduce state size when the variable isn't necesserily used.
8+
9+
You can make any variable or a field an optional by adding a question mark (`?{:tact}`) after its type declaration. The only exceptions are [`map<k, v>{:tact}`](/book/maps) and [`bounced<Msg>{:tact}`](/book/bounced#bounced-messages-in-tact), where you can't make them, inner key/value type (in case of a map) or the inner [Message](/book/structs-and-messages#messages) (in case of a bounced) optional.
10+
11+
Optional variables or optional fields that are not defined hold the `null{:tact}` value by default. You cannot access them without checking for `null{:tact}` first. But if you're certain they are not `null{:tact}` at a given moment, use the [non-null assertion operator `!!{:tact}`](/book/operators#unary-non-null-assert) to access their value.
12+
13+
Trying to access the value of an optional variable or an optional field without using [`!!{:tact}`](/book/operators#unary-non-null-assert) or without checking for `null{:tact}` beforehand will result in a compilation error.
14+
15+
Example of optionals:
16+
17+
```tact
18+
struct StOpt {
19+
opt: Int?; // Int or null
20+
}
21+
22+
message MsOpt {
23+
opt: StOpt?; // Notice, how the struct StOpt is used in this definition
24+
}
25+
26+
contract Optionals {
27+
opt: Int?;
28+
address: Address?;
29+
30+
init(opt: Int?) { // optionals as parameters
31+
self.opt = opt;
32+
self.address = null; // explicit null value
33+
}
34+
35+
receive(msg: MsOpt) {
36+
let opt: Int? = 12; // defining a new variable
37+
if (self.opt != null) { // explicit check
38+
self.opt = opt!!; // using !! as we know that opt value isn't null
39+
}
40+
}
41+
}
42+
```

‎pages/book/composite-types.mdx renamed to ‎pages/book/structs-and-messages.mdx

+3-46
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
# Composite types
1+
# Structs and Messages
22

33
import { Callout } from 'nextra/components'
44

5-
Tact supports a number of [primitive data types](/book/types#primitive-types) that are tailored for smart contract use. However, using individual means of storage often becomes cumbersome, so there are two main ways to combine multiple primitives together: [Structs](#structs) and [Messages](#messages).
6-
7-
Note, while Traits and Contracts are also considered a part of the Tacts type system, one can't pass them around like [Structs](#structs) or [Messages](#messages). Instead, one can obtain the initial state of the given Contract by using the [`initOf{:tact}`](/book/expressions#initof) expression.
5+
Tact supports a number of [primitive data types](/book/types#primitive-types) that are tailored for smart contract use. However, using individual means of storage often becomes cumbersome, so there are [Structs](#structs) and [Messages](#messages) which allow combining types together.
86

97
<Callout type="warning" emoji="⚠️">
108

11-
**Warning**: Currently circular types are **not** possible. This means that struct/message **A** can't have a field of a struct/message **B** that has a field of the struct/message **A**.
9+
**Warning**: Currently circular types are **not** possible. This means that Struct/Message **A** can't have a field of a Struct/Message **B** that has a field of the Struct/Message **A**.
1210

1311
Therefore, the following code **won't** compile:
1412

@@ -105,44 +103,3 @@ This is useful for cases where you want to handle certain opcodes (operation cod
105103
[Jetton Standard in Tact on Tact-by-Example](https://tact-by-example.org/07-jetton-standard)
106104

107105
</Callout>
108-
109-
## Optionals
110-
111-
As it was mentioned in [type system overview](/book/types), most [primitive types](/book/types#primitive-types), [Structs](#structs) and [Messages](#messages) could be nullable. That is, they don't necessarily hold any value, aside from `null{:tact}` — a special value, which represents the intentional absence of any other value.
112-
113-
[Variables](/book/statements#variable-declaration) or fields of [Structs](#structs) and [Messages](#messages) that can hold `null{:tact}` are called "optionals". They're useful to reduce state size when the variable isn't necesserily used.
114-
115-
You can make any variable or a field an optional by adding a question mark (`?{:tact}`) after its type declaration. The only exceptions are [`map<>{:tact}`](/book/types#maps) and [`bounced<>{:tact}`](/book/bounced#bounced-messages-in-tact), where you can't make them, inner key/value type (in case of a map) or the inner [Message](#messages) (in case of a bounced) optional.
116-
117-
Optional variables or optional fields that are not defined hold the `null{:tact}` value by default. You cannot access them without checking for `null{:tact}` first. But if you're certain they are not `null{:tact}` at a given moment, use the non-null assertion operator (`!!{:tact}`) to access their value.
118-
119-
Trying to access the value of an optional variable or an optional field without using `!!{:tact}` or without checking for `null{:tact}` beforehand will result in a compilation error.
120-
121-
Example of optionals:
122-
123-
```tact
124-
struct StOpt {
125-
opt: Int?; // Int or null
126-
}
127-
128-
message MsOpt {
129-
opt: StOpt?; // Notice, how the struct StOpt is used in this definition
130-
}
131-
132-
contract Optionals {
133-
opt: Int?;
134-
address: Address?;
135-
136-
init(opt: Int?) { // optionals as parameters
137-
self.opt = opt;
138-
self.address = null; // explicit null value
139-
}
140-
141-
receive(msg: MsOpt) {
142-
let opt: Int? = 12; // defining a new variable
143-
if (self.opt != null) { // explicit check
144-
self.opt = opt!!; // using !! as we know that opt value isn't null
145-
}
146-
}
147-
}
148-
```

0 commit comments

Comments
 (0)