T
TOLK lang
@tolk_lang
🫧 Tolk v0.10: preparing for serialization — intN, bytesN, coins
This update lays the foundation of future auto-packing to/from cells by solving one critical question:
How should fields be serialized?
✅ Notable changes in Tolk v0.10:
1. Fixed-size integer types:
2. Type
3. Types
4. Replace
5. Trailing comma support
PR on GitHub with detailed info.
❓ Fixed-size integers? In TVM? What?
Imagine Tolk already has structures, and we define an incoming message:
A client sends this message following the TL/B schema:
But how do we tell the compiler that counter_id is int32 and inc_by is int64? This information is missing in the struct definition.
✖ Rejected approaches: why they fail
Several syntax ideas were considered:
Each of these quickly breaks down when handling more complex cases.
For example, how would we handle TL-B
And what about TL/B
With every new case, the syntax becomes more complex, ambiguous, and error-prone.
✔ The solution: `int32` as a first-class type
No annotations. No confusing
This scales perfectly:
These are distinct types. A variable can be
This makes serialization predictable, structured, and error-free.
✔ What about overflow?
A reasonable question: what happens if a value exceeds the limit?
Answer: no runtime overflow or clamping! It's just int at TVM.
* arithmetic works normally – v becomes 256
* no extra gas cost – no runtime bounds checks
* overflow will only happen at serialization
✔ Why is this the best approach?
Think of smart contracts as a black box:
- inputs are encoded (int32, uint64, etc.)
- inside the contract, arithmetic uses full 257-bit precision
- outputs are serialized again — overflow happens only at this stage
This is similar to how mulDivFloor(x,y,z) uses 513-bit precision internally. Your contract keeps precision internally and only enforces constraints at the border with an outside world.
🌳 Tolk will follow a type-based philosophy
This post covered the foundation of automatic serialization. The right way is to have a rich type system. Having nested types, having generics, having aliases — will allow to describe every practical TL/B case, but at a language level.
In v0.10, we introduce
How will
Stay tuned for the next update...
This update lays the foundation of future auto-packing to/from cells by solving one critical question:
How should fields be serialized?
✅ Notable changes in Tolk v0.10:
1. Fixed-size integer types:
int32, uint64, etc.2. Type
coins and function ton("0.05")3. Types
bytesN and bitsN (backed by slices at TVM)4. Replace
"..."c postfixes with stringCrc32("...") functions5. Trailing comma support
PR on GitHub with detailed info.
❓ Fixed-size integers? In TVM? What?
Imagine Tolk already has structures, and we define an incoming message:
struct CounterIncrement {
counter_id: int;
inc_by: int;
}
A client sends this message following the TL/B schema:
counterIncrement
counter_id:int32
inc_by:int64
= CounterIncrement;
But how do we tell the compiler that counter_id is int32 and inc_by is int64? This information is missing in the struct definition.
✖ Rejected approaches: why they fail
Several syntax ideas were considered:
// type casting?
counter_id: int as int32;
inc_by: int as int64;
// inline annotations?
counter_id: int @int32;
inc_by: int @int64;
// annotations above fields?
@serialize(int32)
counter_id: int;
@serialize(int64)
inc_by: int;
Each of these quickly breaks down when handling more complex cases.
For example, how would we handle TL-B
Maybe int32? Would we write:
// this?
inc_by: (int as int32)?;
// or this?
inc_by: int? as int32?;
// or this?
inc_by: Maybe<int> as Maybe<int32>;
And what about TL/B
Both (Maybe int32) int64?
// this?
my_data: Both<Maybe<int as int32>, int as int64>;
// or this?
my_data: Both<Maybe<int>, int> as Both<Maybe<int32>, int64>;
// or how??
With every new case, the syntax becomes more complex, ambiguous, and error-prone.
✔ The solution: `int32` as a first-class type
struct CounterIncrement {
counter_id: int32;
inc_by: int64;
}
No annotations. No confusing
as syntax. No ambiguity.This scales perfectly:
struct MyMsg {
inc_by: int32?;
my_data: (int32?, int64);
}
These are distinct types. A variable can be
int32 and similar:
var op: int32 = ...;
var query_id: uint64 = ...;
This makes serialization predictable, structured, and error-free.
✔ What about overflow?
A reasonable question: what happens if a value exceeds the limit?
var v: uint8 = 255;
v += 1; // ???
Answer: no runtime overflow or clamping! It's just int at TVM.
* arithmetic works normally – v becomes 256
* no extra gas cost – no runtime bounds checks
* overflow will only happen at serialization
struct Resp {
outValue: uint8;
}
resp.outValue = v; // 256
resp.toCell(); // a runtime "overflow" error
✔ Why is this the best approach?
Think of smart contracts as a black box:
- inputs are encoded (int32, uint64, etc.)
- inside the contract, arithmetic uses full 257-bit precision
- outputs are serialized again — overflow happens only at this stage
This is similar to how mulDivFloor(x,y,z) uses 513-bit precision internally. Your contract keeps precision internally and only enforces constraints at the border with an outside world.
🌳 Tolk will follow a type-based philosophy
This post covered the foundation of automatic serialization. The right way is to have a rich type system. Having nested types, having generics, having aliases — will allow to describe every practical TL/B case, but at a language level.
In v0.10, we introduce
intN (fixed integers), bytesN (definite slices), coins (variadic integers), and some more additions. Read the details in the PR.How will
Either L R and even more complex TL/B structures be expressed? Stay tuned for the next update...
❤ 6
🔥 4
👍 3
🤔 1
8 4.1K
Обсуждение 0
Обсуждение не доступно в веб-версии. Чтобы написать комментарий, перейдите в приложение Telegram.
Обсудить в Telegram