diff --git a/pages/book/functions.mdx b/pages/book/functions.mdx index b15625fb..343fe2dc 100644 --- a/pages/book/functions.mdx +++ b/pages/book/functions.mdx @@ -1,5 +1,11 @@ # Functions and their types +{/* TODO: work on terminology & update relevant pages in book/contracts too */} +{/* TODO: global static -> just global, internal -> storage, persistent state -> storage */} +{/* TODO: fix all links leading onto this page */} + +{/* TODO: rewrite this paragraph */} + Functions in Tact could be defined in different ways: * Global static function @@ -23,47 +29,99 @@ fun bar() { } ``` -## Global static functions +## Native functions, `native` [#native] + +{/* TODO Top-level, mappings to FunC */} + +Native functions are direct bindings of FunC functions: + +> **Note** +> Native functions could be also mutable and extension ones. + +```tact +@name(store_uint) +native storeUint(s: Builder, value: Int, bits: Int): Builder; + +@name(load_int) +extends mutates native loadInt(self: Slice, l: Int): Int; +``` + +## Regular functions, `fun` [#fun] + +{/* TODO: Regular functions are ... */} + +### Global [#fun-global] You can define global function anywhere in your program: ```tact fun customPow(a: Int, c: Int): Int { - let res: Int = 1; - repeat(c) { - res *= a; - } - return res; + require(c >= 0, "Can't raise to negative power here!"); + let res = 1; + repeat(c) { res *= a } + return res; } ``` -## Virtual and abstract functions +{/* TODO: Top-level */} -You can allow the contract inheriting a [traits](/book/types#traits) to modify an internal function, if it has the `virtual{:tact}` keyword, using `override{:tact}`. The function can be also marked as `abstract{:tact}`, in which case the inheriting contract has to define its implementation: +### Storage [#fun-storage] + +{/* Internal to traits and contracts. Currently called internal functions, but might as well be called storage ones */} + +## Receivers [#receivers] + +Receiver functions are special functions that are responsible for receiving messages in contracts and could be defined only within a contract or trait. ```tact -trait FilterTrait with Ownable { - // Virtual functions can be overridden by users of this trait - virtual fun filterMessage(): Bool { - return sender() != self.owner; +contract Treasure { + // This means that this contract can receive the comment "Increment" and this function would be called for such messages + receive("Increment") { + self.counter += 1; } - - abstract fun specialFilter(): Bool; } +``` -contract Filter with FilterTrait { - // Overriding default behavior of the FilterTrait - override fun filterMessage(): Bool { - return true; - } +{/* TODO: investigate into attributes */} +{/* TODO: cross-link from and to /book/receive and /book/contracts */} - override fun specialFilter(): Bool { - return true; +### Internal message receivers, `receive` [#internal-receivers] + +{/* TODO */} + +### External message receivers, `external` [#external-receivers] + +{/* TODO */} + +### Bounced message receivers, `bounced` [#bounced-receivers] + +{/* TODO */} + +## Attributes [#attributes] + +{/* When applied... */} + +### Off-chain functions, `get` [#attributes-get] + +{/* TODO */} + +Off-chain functions, otherwise known as _getter_ functions, define special functions, that are unaccessible from other contracts and exported only to off-chain world. + +Moreover, they cannot modify the contract's state as their only purpose is to read and retrieve the information from the contract. + +Notice, however, that you can evaluate expressions and create local variables just fine. It's only those storage variables that cannot be modified. + +```tact +contract Treasure { + get fun counter(): Int { + return self.counter; } } -```` +``` + +### Extension functions, `extends` [#attributes-extends] -## Extension function +{/* TODO */} Extension functions allow you to implement extensions for any possible type. @@ -73,14 +131,16 @@ Extension functions allow you to implement extensions for any possible type. ```tact extends fun customPow(self: Int, c: Int): Int { let res: Int = 1; - repeat(c) { - res *= self; - } + repeat(c) { res *= self } return res; } ``` -## Mutable functions +### Mutation functions, `mutates` [#attributes-mutates] + +{/* TODO */} + +A sub-set of extension functions... Mutable functions are performing mutation of a value replacing it with an execution result. To perform mutation, the function must change the `self` value. @@ -94,42 +154,38 @@ extends mutates fun customPow(self: Int, c: Int) { } ``` -## Native functions - -Native functions are direct bindings of FunC functions: +### `abstract` [#attributes-abstract] -> **Note** -> Native functions could be also mutable and extension ones. +### `virtual` [#attributes-virtual] -```tact -@name(store_uint) -native storeUint(s: Builder, value: Int, bits: Int): Builder; +### `override` [#attributes-override] -@name(load_int) -extends mutates native loadInt(self: Slice, l: Int): Int; -``` +{/* TODO: "virtual and abstract functions" split this description in three consecutive parts */} -## Receiver functions +You can allow the contract inheriting [traits](/book/types#traits) to modify an internal function, if it has the `virtual{:tact}` keyword, using `override{:tact}`. -Receiver functions are special functions that are responsible for receiving messages in contracts and could be defined only within a contract or trait. +The function can be also marked as `abstract{:tact}`, in which case the inheriting contract has to define its implementation: ```tact -contract Treasure { - // This means that this contract can receive the comment "Increment" and this function would be called for such messages - receive("Increment") { - self.counter += 1; +trait FilterTrait with Ownable { + // Virtual functions can be overridden by users of this trait + virtual fun filterMessage(): Bool { + return sender() != self.owner; } -} -``` -## Getter Functions + abstract fun specialFilter(): Bool; +} -Getter functions define getters on smart contracts and can be defined only within a contract or trait. +contract Filter with FilterTrait { + // Overriding default behavior of the FilterTrait + override fun filterMessage(): Bool { + return true; + } -```tact -contract Treasure { - get fun counter(): Int { - return self.counter; + override fun specialFilter(): Bool { + return true; } } ``` + +{/* TODO: `inline` — in a separate PR, targeting https://github.com/tact-lang/tact-docs/issues/241 */}