Tolk vs FunC: in short
Tolk is much more similar to TypeScript and Kotlin than C and Lisp. But it still gives you complete control over the TVM assembler since it has a FunC kernel inside.
- Functions are declared via
fun
, get methods viaget fun
, variables viavar
, immutable variables viaval
, putting types on the right; parameter types are mandatory; return type can be omitted (auto inferred), as well as for locals; specifiersinline_ref
and others are@
attributes
global storedV: int;
fun parseData(cs: slice): cell {
var flags: int = cs.loadMessageFlags();
...
}
@inline
fun sum(a: int, b: int) { // auto inferred int
val both = a + b; // same
return both;
}
get fun currentCounter(): int { ... }
- No
impure
, it's by default, the Tolk compiler won't drop user function calls - Not
recv_internal
andrecv_external
, butonInternalMessage
/onExternalMessage
/onBouncedMessage
2+2
is 4, not an identifier; identifiers are alpha-numeric; use namingconst OP_INCREASE
instead ofconst op::increase
;cell
andslice
are valid identifiers (not keywords)- Logical operators AND
&&
, OR||
, NOT!
are supported - Syntax improvements:
;; comment
→// comment
{- comment -}
→/* comment */
#include
→import
, with a strict rule import what you use~ found
→!found
(for true/false only, obviously) (true is -1, like in FunC)v = null()
→v = null
null?(v)
→v == null
, same forbuilder_null?
and others~ null?(v)
→c != null
throw(excNo)
→throw excNo
catch(_, _)
→catch
catch(_, excNo)
→catch(excNo)
throw_unless(excNo, cond)
→assert(cond, excNo)
throw_if(excNo, cond)
→assert(!cond, excNo)
return ()
→return
do ... until (cond)
→do ... while (!cond)
elseif
→else if
ifnot (cond)
→if (!cond)
"..."c
→stringCrc32("...")
(and other postfixes also)
- A function can be called even if declared below; forward declarations not needed; the compiler at first does parsing, and then it does symbol resolving; there is now an AST representation of source code
- stdlib functions renamed to
verboseclear names, camelCase style; it's now embedded, not downloaded from GitHub; it's split into several files; common functions available always, more specific available withimport "@stdlib/tvm-dicts"
, IDE will suggest you; here is a mapping - No
~
tilda methods;cs.loadInt(32)
modifies a slice and returns an integer;b.storeInt(x, 32)
modifies a builder;b = b.storeInt()
also works since it is not only modifies but returns; chained methods work identically to JS, they returnself
; everything works exactly as expected, similar to JS; no runtime overhead, exactly same Fift instructions; custom methods are created with ease; tilda~
does not exist in Tolk at all; more details here - Clear and readable error messages on type mismatch
bool
type support- Indexed access
tensorVar.0
andtupleVar.0
support - Nullable types
T?
, null safety, smart casts, operator!
- Union types and pattern matching (for types and for expressions, switch-like behavior)
- Type aliases are supported
- Structures are supported
- Generics are supported
- Methods (as extension functions) are supported
- Trailing comma is supported
- Semicolon after the last statement in a block is optional
- Fift output contains original .tolk lines as comments
- Auto-packing to/from cells — for any types
- Universal createMessage to avoid manual cells composition
- Auto-detect and inline functions at the compiler level
- Various optimizations for gas efficiency
Tooling around
- tolk-js WASM wrapper for blueprint
Tolk vs FunC gas benchmarks
The Tolk-bench repository contains several contracts migrated from FunC to Tolk, preserving all logic and passing the same tests.
As you see, not only does the code become readable, but gas usage is noticeably reduced. And there are no tricks here—just clean, consistent logic — whether it's a Jetton or a Wallet.
The rule is simple: if you write code the way the language encourages — gas will take care of itself.
See also
Was this article useful?