Let's now take a look at the syntax and semantics for defining new functions in Nessa.
## Syntax
You can define and use a function using the following syntax:
```
// Definition
fn funtion_name_1(param_1: Type_1, param_2: Type_2, ...) -> Return_type {
[...]
return some_expression;
}
// Usage
let variable: Return_type = funtion_name_1(something_1, something_2);
```
Of course, you can have as many `return` statements as you want (or none at all if your function does not return anything), but
this is a simple example. Now let's modify this code to create a generic function:
```
// Definition
fn<T, G> funtion_name_2(param_1: Type_1, param_2: Type_2, ...) -> Return_type {
[...]
let variable_1: 'T = something;
let variable_2: Array<'G> = something;
[...]
return some_expression;
}
// Explicit usage
let variable_1: Return_type = funtion_name_2<Type_3, Type_4>(something_1, something_2);
// Type parameter inference (when unambiguous)
let variable_2: Return_type = funtion_name_2(something_1, something_2);
```
Here you can see that putting `<T, G>` after the `fn` keyword in the definition **defines** the templates `T` and `G` inside the function body.
They **cannot** be used outside the function body.
> ***Note:*** the `<T, G>` syntax might change to `<'T, 'G>` in a future release for ease of highlighting and uniformization.
## Examples
Let's create some common examples to see how functions work in this language. First off, let's create two factorial functions, a recursive and an iterative one:
```
fn factorial_recursive(n: Int) -> Int {
if n == 1 {
return 1;
}
return n * factorial_recursive(n - 1);
}
fn factorial_iterative(n: Int) -> Int {
let res = 1;
while n > 1 {
res = res * n;
n = n - 1;
}
return res.deref();
}
```
Now let's dive into generics and make a function that counts how many elements in an array are equal to one given as a parameter:
```
fn<T> count(array: &Array<'T>, elem: &'T) -> Int {
let res = 0;
for i in array {
if i == elem {
res = res + 1;
}
}
return res.deref();
}
```