Skip to main content

Tolk vs FunC: standard library

FunC has a rich standard library, known as "stdlib.fc" file. It's quite low-level and contains many asm functions closely related to TVM instructions.

Tolk also has a standard library based on a FunC one. Three main differences:

  1. It's split into multiple files: common.tolk, tvm-dicts.tolk, and others. Functions from common.tolk are always available. Functions from other files are available after import:
import "@stdlib/tvm-dicts"

beginCell() // available always
createEmptyDict() // available due to import
  1. You don't need to download it from GitHub; it's a part of Tolk distribution.
  2. Tolk has functions and methods (called via dot), lots of global FunC functions became methods of builder/slice/etc. (and can't be called as functions)

Functions vs methods

In FunC, there are no methods, actually. All functions are global-scoped.
You just call any function via dot:

;; FunC
cell config_param(int x) asm "CONFIGOPTPARAM";

config_param(16); ;; ok
16.config_param(); ;; also ok...

So, when you call b.end_cell(), you actually call a global function end_cell. Since all functions are global-scoped, there are no "short methods."

someTuple.tuple_size();
;; why not someTuple.size()? because it's a global function:
;; int tuple_size(tuple t)

Tolk separates functions and methods like it's done in most languages:

  1. functions can NOT be called via dot, only methods can
  2. methods can have short names, they don't conflict
// FunC
someCell.cell_hash(); // or cell_hash(someCell)
someSlice.slice_hash();

// Tolk
someCell.hash(); // the only possible
someSlice.hash();

A list of renamed functions

If the Required import column is empty, a function is available without imports.

Note that some functions were deleted because they either can be expressed syntactically, or they were very uncommon in practice.

The table is "sorted" in a way how functions are declared in stdlib.fc:

FunC nameTolk nameRequired import
empty_tuplecreateEmptyTuple
t~tpusht.push(v)
first(t) or dot t.first()t.first()
at(t,i) or dot t.at(i)t.get(i) or just t.0 etc.
touch(v) or dotv.stackMoveToTop()tvm-lowlevel
impure_touch(deleted)
single(deleted)
unsingle(deleted)
pair(deleted)
unpair(deleted)
triple(deleted)
untriple(deleted)
tuple4(deleted)
untuple4(deleted)
second(deleted)
third(deleted)
fourth(deleted)
pair_first(deleted)
pair_second(deleted)
triple_first(deleted)
triple_second(deleted)
triple_third(deleted)
minmaxminMax
nowblockchain.now
my_addresscontract.getAddress
get_balance + pair_firstcontract.getOriginalBalance
cur_ltblockchain.logicalTime
block_ltblockchain.currentBlockLogicalTime
cell_hash(c) or dotc.hash()
slice_hash(s) or dots.hash()
string_hash(s) or dots.bitsHash()
check_signatureisSignatureValid
check_data_signatureisSliceSignatureValid
compute_data_size(c) or dotc.calculateSizeStrict()
slice_compute_data_size(s) or dots.calculateSizeStrict()
c.compute_data_size?() or dotc.calculateSize()
slice_compute_data_size?() or dots.calculateSize()
~dumpdebug.print
~strdumpdebug.printString
dump_stackdebug.dumpStack
get_datacontract.getData
set_datacontract.setData
get_c3getTvmRegisterC3tvm-lowlevel
set_c3setTvmRegisterC3tvm-lowlevel
blesstransformSliceToContinuationtvm-lowlevel
accept_messageacceptExternalMessage
set_gas_limitsetGasLimit
buy_gas(deleted)
commitcommitContractDataAndActions
divmoddivMod
moddivmodDiv
muldivmulDivFloor
muldivrmulDivRound
muldivcmulDivCeil
muldivmodmulDivMod
begin_parsebeginParse
end_parse(s) or dots.assertEnd()
load_refloadRef
preload_refpreloadRef
load_intloadInt
load_uintloadUint
preload_intpreloadInt
preload_uintpreloadUint
load_bitsloadBits
preload_bitspreloadBits
load_gramsloadCoins
load_coinsloadCoins
skip_bitss.skipBits
first_bitsgetFirstBits
skip_last_bitsremoveLastBits
slice_lastgetLastBits
load_dictloadDict
preload_dictpreloadDict
skip_dictskipDict
load_maybe_refloadMaybeRef
preload_maybe_refpreloadMaybeRef
cell_depth(c) or dotc.depth()
slice_refs(s) or dots.remainingRefsCount()
slice_bits(s) or dots.remainingBitsCount()
slice_bits_refs(s) or dots.remainingBitsAndRefsCount()
slice_empty?(s) or dots.isEnd()
slice_data_empty?(s) or dots.isEndOfBits()
slice_refs_empty?(s) or dots.isEndOfRefs()
slice_depth(s) or dots.depth()
equal_slice_bits(a,b) or dota.bitsEqual(b)
builder_refs(b) or dotb.refsCount()
builder_bits(b) or dotb.bitsCount()
builder_depth(b) or dotb.depth()
begin_cellbeginCell
end_cellendCell
store_refstoreRef
store_uintstoreUint
store_intstoreInt
store_slicestoreSlice
store_gramsstoreCoins
store_coinsstoreCoins
store_dictstoreDict
store_maybe_refstoreMaybeRef
store_builderstoreBuilder
load_msg_addrloadAddress
parse_addr(deleted)
parse_std_addrparseStandardAddress
parse_var_addr(deleted)
config_paramblockchain.configParam
raw_reservereserveToncoinsOnBalance
raw_reserve_extrareserveExtraCurrenciesOnBalance
send_raw_messagesendRawMessage
set_codecontract.setCodePostponed
randomrandom.uint256
randrandom.range
get_seedrandom.getSeed
set_seedrandom.setSeed
randomizerandom.initializeBy
randomize_ltrandom.initialize
dumpdebug.print
strdumpdebug.printString
dump_stkdebug.dumpStack
empty_listcreateEmptyListlisp-lists
conslistPrependlisp-lists
unconslistSplitlisp-lists
list_nextlistNextlisp-lists
carlistGetHeadlisp-lists
cdrlistGetTaillisp-lists
new_dictcreateEmptyDicttvm-dicts
dict_empty?(d) or dotd.dictIsEmptytvm-dicts
idict_set_refiDictSetReftvm-dicts
udict_set_refuDictSetReftvm-dicts
idict_get_refiDictGetRefOrNulltvm-dicts
idict_get_ref?iDictGetReftvm-dicts
udict_get_ref?uDictGetReftvm-dicts
idict_set_get_refiDictSetAndGetRefOrNulltvm-dicts
udict_set_get_refiDictSetAndGetRefOrNulltvm-dicts
idict_delete?iDictDeletetvm-dicts
udict_delete?uDictDeletetvm-dicts
idict_get?iDictGettvm-dicts
udict_get?uDictGettvm-dicts
idict_delete_get?iDictDeleteAndGettvm-dicts
udict_delete_get?uDictDeleteAndGettvm-dicts
udict_setuDictSettvm-dicts
idict_setiDictSettvm-dicts
dict_setsDictSettvm-dicts
udict_add?uDictSetIfNotExiststvm-dicts
udict_replace?uDictSetIfExiststvm-dicts
idict_add?iDictSetIfNotExiststvm-dicts
idict_replace?iDictSetIfExiststvm-dicts
udict_set_builderuDictSetBuildertvm-dicts
idict_set_builderiDictSetBuildertvm-dicts
dict_set_buildersDictSetBuildertvm-dicts
udict_add_builder?uDictSetBuilderIfNotExiststvm-dicts
udict_replace_builder?uDictSetBuilderIfExiststvm-dicts
idict_add_builder?iDictSetBuilderIfNotExiststvm-dicts
idict_replace_builder?iDictSetBuilderIfExiststvm-dicts
udict_delete_get_minuDictDeleteFirstAndGettvm-dicts
idict_delete_get_miniDictDeleteFirstAndGettvm-dicts
dict_delete_get_minsDictDeleteFirstAndGettvm-dicts
udict_delete_get_maxuDictDeleteLastAndGettvm-dicts
idict_delete_get_maxiDictDeleteLastAndGettvm-dicts
dict_delete_get_maxsDictDeleteLastAndGettvm-dicts
udict_get_min?uDictGetFirsttvm-dicts
udict_get_max?uDictGetLasttvm-dicts
udict_get_min_ref?uDictGetFirstAsReftvm-dicts
udict_get_max_ref?uDictGetLastAsReftvm-dicts
idict_get_min?iDictGetFirsttvm-dicts
idict_get_max?iDictGetLasttvm-dicts
idict_get_min_ref?iDictGetFirstAsReftvm-dicts
idict_get_max_ref?iDictGetLastAsReftvm-dicts
udict_get_next?uDictGetNexttvm-dicts
udict_get_nexteq?uDictGetNextOrEqualtvm-dicts
udict_get_prev?uDictGetPrevtvm-dicts
udict_get_preveq?uDictGetPrevOrEqualtvm-dicts
idict_get_next?iDictGetNexttvm-dicts
idict_get_nexteq?iDictGetNextOrEqualtvm-dicts
idict_get_prev?iDictGetPrevtvm-dicts
idict_get_preveq?iDictGetPrevOrEqualtvm-dicts
udict::delete_get_minuDictDeleteFirstAndGettvm-dicts
idict::delete_get_miniDictDeleteFirstAndGettvm-dicts
dict::delete_get_minsDictDeleteFirstAndGettvm-dicts
udict::delete_get_maxuDictDeleteLastAndGettvm-dicts
idict::delete_get_maxiDictDeleteLastAndGettvm-dicts
dict::delete_get_maxsDictDeleteLastAndGettvm-dicts
pfxdict_get?prefixDictGettvm-dicts
pfxdict_set?prefixDictSettvm-dicts
pfxdict_delete?prefixDictDeletetvm-dicts

A list of added functions

Tolk standard library has some functions missing in FunC but is pretty typical for everyday tasks.

Since Tolk is actively developed, and its standard library changes, it better considers the tolk-stdlib/ folder in sources here. Besides functions, there some constants were added: SEND_MODE_*, RESERVE_MODE_*, etc.

When FunC becomes deprecated, the documentation about Tolk stdlib will be rewritten entirely, anyway.

Remember that all the functions above are wrappers over the TVM assembler. If something is missing, you can quickly wrap any TVM instruction yourself.

Some functions became mutating, not returning a copy

FunCTolk
int flags = cs~load_uint(32);var flags = cs.loadUint(32);
dict~udict_set(...);dict.uDictSet(...);
......

Most FunC functions used with ~ tilda in practice now mutate the object; see examples above.

For example, if you used dict~udict_set(…), just use dict.uDictSet(…), and everything is fine. But if you used dict.udict_set(…) to obtain a copy, you'll need to express it another way.

Read about mutability.

How does embedded stdlib work under the hood?

As told above, all standard functions are available out of the box. You need import for non-common functions (it's intentional), but still, no external downloads.

It works the following way.

The first thing the Tolk compiler does at the start is locate the stdlib folder by searching predefined paths relative to an executable binary. For example, if you launch the Tolk compiler from a package installed (e.g. /usr/bin/tolk), locate stdlib in /usr/share/ton/smartcont. You may pass the TOLK_STDLIB env variable if you have a non-standard installation. It's standard practice for compilers.

A WASM wrapper tolk-js also contains stdlib. So, when you take tolk-js or blueprint, all stdlib functions are still available out of the box.

JetBrains and VS Code IDE plugins also auto-locate stdlib to provide auto-completion. If you use blueprint, it automatically installs tolk-js; therefore, folder node_modules/@ton/tolk-js/ exists in your project file structure. Inside are common.tolk, tvm-dicts.tolk, and others.

Was this article useful?