> For the complete documentation index, see [llms.txt](https://bagus-cahyono.gitbook.io/programming-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bagus-cahyono.gitbook.io/programming-notes/rust/rustlings_exercise/02_functions.md).

# Functions

* Declare function using `fn`, reference: <https://doc.rust-lang.org/std/primitive.fn.html>
* Rust code uses snake case as the conventional style for function and variable names.
* In function signatures, you must declare the type of each parameter.
* When defining multiple parameters, separate the parameter declarations with commas.
* Functions can return values to the code that calls them. We don’t name return values, but we must declare their type after an arrow `->`.
* Rust have **statements** and **expressions**:
  * **Statements** are instructions that perform some action and do not return a value.
  * **Expressions** evaluate to a resultant value. Let’s look at some examples.
  * If you add a semicolon to the end of an expression, you turn it into a statement, and it will then not return a value.
* You can return early from a function by using the `return` keyword and specifying a value, but most functions return the last expression implicitly.
* Reference: [Functions](https://doc.rust-lang.org/book/ch03-03-how-functions-work.html)

## functions1.rs

```rust
// Add some function with the name `call_me` without arguments or a return value.
fn call_me() {
    println!("called")
}

fn main() {
    call_me(); // Don't change this line
}
```

* We just need to add a new function called `call_me` without any return value.
* Rust code uses snake case as the conventional style for function and variable names, in which all letters are lowercase and underscores separate words.
* Reference: <https://doc.rust-lang.org/book/ch03-03-how-functions-work.html>

## functions2.rs

```rust
// Add the missing type of the argument `num` after the colon `:`.
// Lets use i32 for the argument tyoe.
fn call_me(num: i32) {
    for i in 0..num {
        println!("Ring! Call number {}", i + 1);
    }
}

fn main() {
    call_me(3);
}
```

* In function signatures, you must declare the type of each parameter.

  > This is a deliberate decision in Rust’s design: requiring type annotations in function definitions means the compiler almost never needs you to use them elsewhere in the code to figure out what type you mean. The compiler is also able to give more helpful error messages if it knows what types the function expects.
* When defining multiple parameters, separate the parameter declarations with commas.
* So we just need to add `i32` as the arguments/parameter type.

## functions3.rs

```rust
fn call_me(num: u8) {
    for i in 0..num {
        println!("Ring! Call number {}", i + 1);
    }
}

fn main() {
    // Add parameters to call_me function.
    call_me(5);
}
```

* `call_me` function expect an argument/parameter, add `5` as parameter since the function expect type `u8`.

## functions4.rs

```rust
// This store is having a sale where if the price is an even number, you get 10
// Rustbucks off, but if it's an odd number, it's 3 Rustbucks off.
// Don't worry about the function bodies themselves, we are only interested in
// the signatures for now.

fn is_even(num: i64) -> bool {
    num % 2 == 0
}

// 
fn sale_price(price: i64) -> i64 {
    if is_even(price) {
        price - 10
    } else {
        price - 3
    }
}

fn main() {
    let original_price = 51;
    println!("Your sale price is {}", sale_price(original_price));
}
```

* Functions can return values to the code that calls them. We don’t name return values, but we must declare their type after an arrow `->`.
* In this exercise we just need to add return type as `i64`.

## functions5.rs

```rust
// Remove the semicolon to make it as expression
fn square(num: i32) -> i32 {
    num * num
}

fn main() {
    let answer = square(3);
    println!("The square of 3 is {answer}");
}
```

* Rust have **statements** and **expressions**:
  * **Statements** are instructions that perform some action and do not return a value.
  * **Expressions** evaluate to a resultant value. Let’s look at some examples.
  * If you add a semicolon to the end of an expression, you turn it into a statement, and it will then not return a value.
* You can return early from a function by using the return keyword and specifying a value, but most functions return the last expression implicitly.
* In this exercise the `square` functions expect a return value, but the function body only have one line statement. By removing the semicolon `;` we make it as an expression and will return the value of `num * num`
