# Function¶

## The function definition¶

You can define anonymous functions, you can also define named functions (but can not define the global function name), you can also create a closure

Such as

```let abc = function(n: number)
return n + 1
end
return n+2
end

let M = {}
function M:sayHi()
if 2 < 1 then
return
end
print('Hi')
end
```

The ‘return’ statement is acceptable in the code block of a function, which indicating that 0 or a value is returned to the caller, or that there is no return statement. But any other statement after ‘return’ statement is not allowed,

Such as

```let abc = function (n: number)
return n+1
pprint(n)             -- Here comes an error, 'return' statement should not be followed by any other statements
end
```

The parameter declaration of a function can be declared with parameter types, such as： (name: string, age: int)，The compile time type for this parameter is the object type without type declaration

## Simpler function expression¶

The syntax defined by the above function can also define anonymous functions, but sometimes some simple anonymous functions are not convenient to write, so provide a more simplified function expression syntax

• Single expression function

The function body can only be a single expression, and must be in the same row as the function argument

The grammar rules are as follows:

```Args => Expr
```

Such as:

```let a1 = (a: number, b: number) => a + b  -- a1 type is(number, number) => number
let a2 = a1(1, 2) -- result is 3
```
• Multi-line expression function

The function body can be multiple statements, and does not limit must be on the same line

The grammar rules are as follows:

```Args => do
Block
end
```

Such as:

```let a3 = (a: number, b: number) => do
pprint(a + b)
return a + b
end -- a3 type as(number, number) => number
let a4 = a3(1, 2) -- output 3 and a4 is set to 3
```

## Function Call¶

• There are two types of syntax for a function call. One is a function object or a variable followed by (), which can pass in a number of parameters, such as
```var result = sayHi('glua', 123)
```
• Another function call syntax is that if the function call has only one argument and this parameter is literal or table literal, you can omit the parenthesis here, for example
```var result = print 'hello'
var result2 = pprint {hello: 2}
```
• In a function call, if returned a value, it will return to the caller, such as in the example above, to assign the return value to result.
• The function may have a return statement in the different branches of the functional body code, which will return the first return value based on the actual running results. In the compile period, the return statements returns compile period type of the value to the union to analyze the return type of the function. Such as
```let function hello(n: number)   -- Because the return statement in the function body of this function is int,string, int, so the return type of this function is int | string
if n > 10 then
return n            -- This return statement returns an int type
elseif n > 3 then
return 'hello'      -- This return statement returns an String type
else
return 0            -- This return statement returns an int type
end
end
```
• The function definition has a syntax such as ‘function M:init() print(self.name) end’, This colon syntax is equivalent to a dot, but automatically adds a self parameter to express the M object, The call to this function is similar with M:init() call, which in the runtime automatically puts the M object in the first parameter of the M.init function as the self parameter. But notice that the API function definition of the contract supports only the colon syntax. Such as
```var t1 = {name: 'glua'}
function t1:sayHello()
```
• The function call requires that the parameter type when the function is defined is the same as the type of variable or value used in the actual call, otherwise it will be reported incorrectly