|
1 | | -# Function calls |
| 1 | +# Functions |
2 | 2 |
|
3 | 3 | Constant size values stored on the stack or in memory can be passed into and returned by functions. |
| 4 | + |
| 5 | +> **<sup>Syntax</sup>**\ |
| 6 | +> _Function_ :\ |
| 7 | +> _FunctionQualifiers_ `fn` [IDENTIFIER]\ |
| 8 | +> `(` _FunctionParameters_<sup>?</sup> `)`\ |
| 9 | +> _FunctionReturnType_<sup>?</sup>\ |
| 10 | +> `{`\ |
| 11 | +> _FunctionStatements_<sup>*</sup>\ |
| 12 | +> `}` |
| 13 | +> |
| 14 | +> _FunctionQualifiers_ :\ |
| 15 | +> `pub`<sup>?</sup> |
| 16 | +> |
| 17 | +> _FunctionStatements_ :\ |
| 18 | +> [_ReturnStatement_]\ |
| 19 | +> | [_VariableDeclarationStatement_]\ |
| 20 | +> | [_AssignStatement_]\ |
| 21 | +> | [_AugmentedAssignStatement_]\ |
| 22 | +> | [_ForStatement_]\ |
| 23 | +> | [_WhileStatement_]\ |
| 24 | +> | [_IfStatement_]\ |
| 25 | +> | [_AssertStatement_]\ |
| 26 | +> | [_BreakStatement_]\ |
| 27 | +> | [_ContinueStatement_]\ |
| 28 | +> | [_RevertStatement_]\ |
| 29 | +> | [_Expression_]\ |
| 30 | +> |
| 31 | +> _FunctionParameters_ :\ |
| 32 | +> `self`<sup>?</sup> | `self,`<sup>?</sup> _FunctionParam_ (`,` _FunctionParam_)<sup>\*</sup> `,`<sup>?</sup> |
| 33 | +> |
| 34 | +> _FunctionParam_ :\ |
| 35 | +> _FunctionParamLabel_<sup>?</sup> [IDENTIFIER] `:` [_Types_] |
| 36 | +> |
| 37 | +> _FunctionParamLabel_ :\ |
| 38 | +> _ | [IDENTIFIER] |
| 39 | +> |
| 40 | +> _FunctionReturnType_ :\ |
| 41 | +> `->` [_Types_] |
| 42 | +
|
| 43 | + |
| 44 | +A _function_ definition consists of name and code block along with an optional |
| 45 | +list of parameters and return value. Functions are declared with the |
| 46 | +keyword `fn`. Functions may declare a set of *input* parameters, |
| 47 | +through which the caller passes arguments into the function, and |
| 48 | +the *output* [*type*][_Types_] of the value the function will return to its caller |
| 49 | +on completion. |
| 50 | + |
| 51 | +When referred to, a _function_ yields a first-class *value* of the |
| 52 | +corresponding zero-sized [*function type*][_FunctionTypes_], which |
| 53 | +when called evaluates to a direct call to the function. |
| 54 | + |
| 55 | +A function header prepends a set or curly brackets `{...}` which contain the function body. |
| 56 | + |
| 57 | +For example, this is a simple function: |
| 58 | + |
| 59 | +```fe |
| 60 | +fn add(x: u256, y: u256) -> u256 { |
| 61 | + return x + y |
| 62 | +} |
| 63 | +``` |
| 64 | + |
| 65 | +Functions can be defined inside of a contract, inside of a struct, or at the |
| 66 | +"top level" of a module (that is, not nested within another item). |
| 67 | + |
| 68 | +Example: |
| 69 | + |
| 70 | +```fe |
| 71 | +fn add(_ x: u256, _ y: u256) -> u256 { |
| 72 | + return x + y |
| 73 | +} |
| 74 | +
|
| 75 | +contract CoolCoin { |
| 76 | + balance: Map<address, u256> |
| 77 | +
|
| 78 | + fn transfer(mut self, from sender: address, to recipient: address, value: u256) -> bool { |
| 79 | + if self.balance[sender] < value { |
| 80 | + return false |
| 81 | + } |
| 82 | + self.balance[sender] -= value |
| 83 | + self.balance[recipient] += value |
| 84 | + return true |
| 85 | + } |
| 86 | + pub fn demo(mut self) { |
| 87 | + let ann: address = 0xaa |
| 88 | + let bob: address = 0xbb |
| 89 | + self.balance[ann] = 100 |
| 90 | +
|
| 91 | + let bonus: u256 = 2 |
| 92 | + let value: u256 = add(10, bonus) |
| 93 | + let ok: bool = self.transfer(from: ann, to: bob, value) |
| 94 | + } |
| 95 | +} |
| 96 | +``` |
| 97 | + |
| 98 | +Function parameters have optional labels. When a function is called, the |
| 99 | +arguments must be labeled and provided in the order specified in the |
| 100 | +function definition. |
| 101 | + |
| 102 | +The label of a parameter defaults to the parameter name; a different label |
| 103 | +can be specified by adding an explicit label prior to the parameter name. |
| 104 | +For example: |
| 105 | +```fe |
| 106 | +fn encrypt(msg cleartext: u256, key: u256) -> u256 { |
| 107 | + return cleartext ^ key |
| 108 | +} |
| 109 | +
|
| 110 | +fn demo() { |
| 111 | + let out: u256 = encrypt(msg: 0xdecafbad, key: 0xfefefefe) |
| 112 | +} |
| 113 | +``` |
| 114 | + |
| 115 | +Here, the first parameter of the `encrypt` function has the label `msg`, |
| 116 | +which is used when calling the function, while the parameter name is |
| 117 | +`cleartext`, which is used inside the function body. The parameter name |
| 118 | +is an implementation detail of the function, and can be changed without |
| 119 | +modifying any function calls, as long as the label remains the same. |
| 120 | + |
| 121 | +When calling a function, a label can be omitted when the argument is |
| 122 | +a variable with a name that matches the parameter label. Example: |
| 123 | + |
| 124 | +```fe,ignore |
| 125 | +let msg: u256 = 0xdecafbad |
| 126 | +let cyf: u256 = encrypt(msg, key: 0x1234) |
| 127 | +``` |
| 128 | + |
| 129 | +A parameter can also be specified to have no label, by using `_` in place of a |
| 130 | +label in the function definition. In this case, when calling the function, the |
| 131 | +corresponding argument must not be labeled. Example: |
| 132 | + |
| 133 | +```fe |
| 134 | +fn add(_ x: u256, _ y: u256) -> u256 { |
| 135 | + return x + y |
| 136 | +} |
| 137 | +fn demo() { |
| 138 | + let sum: u256 = add(16, 32) |
| 139 | +} |
| 140 | +``` |
| 141 | + |
| 142 | +Functions defined inside of a contract or struct may take [`self`][SELF] as a |
| 143 | +parameter. This gives the function the ability to read and write contract |
| 144 | +storage or struct fields, respectively. If a function takes `self` |
| 145 | +as a parameter, the function must be called via `self`. For example: |
| 146 | + |
| 147 | +```fe,ignore |
| 148 | +let ok: bool = self.transfer(from, to, value) |
| 149 | +``` |
| 150 | +`self` is expected to come *first* parameter in the function's parameter list. |
| 151 | + |
| 152 | + |
| 153 | +Functions can also take a [`Context`][CONTEXT] object which gives access to EVM features that read or write |
| 154 | +blockchain and transaction data. `Context` is expected to be *first* in the function's parameter list |
| 155 | +unless the function takes `self`, in which case `Context` should come second. |
| 156 | + |
| 157 | + |
| 158 | +[NEWLINE]: ../lexical_structure/tokens.md#newline |
| 159 | +[IDENTIFIER]: ../lexical_structure/identifiers.md |
| 160 | +[_Types_]: ../type_system/types/index.md |
| 161 | +[_FunctionTypes_]: ../type_system/types/function.md |
| 162 | +[SELF]: ./self.md |
| 163 | +[CONTEXT]: ./context.md |
| 164 | +[_ReturnStatement_]: ../statements/return.md |
| 165 | +[_VariableDeclarationStatement_]: ../statements/let.md |
| 166 | +[_AssignStatement_]: ../statements/assign.md |
| 167 | +[_AugmentedAssignStatement_]: ../statements/augassign.md |
| 168 | +[_ForStatement_]: ../statements/for.md |
| 169 | +[_WhileStatement_]: ../statements/for.md |
| 170 | +[_IfStatement_]: ../statements/if.md |
| 171 | +[_AssertStatement_]: ../statements/assert.md |
| 172 | +[_BreakStatement_]: ../statements/break.md |
| 173 | +[_ContinueStatement_]: ../statements/continue.md |
| 174 | +[_RevertStatement_]: ../statements/revert.md |
| 175 | +[_Expression_]: ../expressions/index.md |
0 commit comments