Just as with control flow, doing useful things is a whole lot easier if you have functions available. They're there in every major high-level language, and they're there in Rust as well.

Functions

Functions in Rust are defined with the fn keyword (often pronounced "fun", or if you're feeling edgy, "effin'") followed by the function name, parameter list, return type, and function body. That's a few words, so let's just see an example and break it down.

Let's pretend that for some totally-not-contrived reason, we need a function which adds 10 to whatever argument we pass in. We give it 5, we want to get back 15. And let's also pretend we only care about 32-bit unsigned integers. That function would look something like this:

#![allow(unused)]
fn main() {
fn add_10(x: u32) -> u32 {
    let value = x + 10;
    value
}
}

fn says we're starting a function, and add_10 gives it a name.

Then we have the parameter list. We only have one thing: x: u32, which says we'll accept a parameter named x with the type u32.

The -> u32 is our return type; if you omit it, it's the same as writing -> (), or returning the unit type (kind of like the return type void in TypeScript or C/C++).

Then we have the function body. This is a block like we talked about in control flow. Inside we have two lines. The first creates a variable named value, and the second returns it implicitly.

Examples

Now we have everything we need to do some more more interesting things. We'll walk through one example here, then you can work through the other one on your own.

Let's take the classic Fibonacci function. First we create our main function as every program needs, we also create a stub. We'll just return a dummy value for now.

fn main() {
    let x = fibonacci(10);
    println!("{x}");
}

fn fibonacci(n: u32) -> u32 {
    0
}

Now we need to fill in that function body. It's a straightforward translation from the algorithm:

fn main() {
    let x = fibonacci(10);
    println!("{x}");
}

fn fibonacci(n: u32) -> u32 {
    if n < 2 {
        return n;
    }

    fibonacci(n-1) + fibonacci(n-2)
}

And now it should print 55!

Now, one to try on your own. I'll give you the main:

fn main() {
    fizzbuzz_up_to(100);
}

Now you should define a function named fizzbuzz_up_to which takes a parameter as a number and does Fizzbuzz. You'll need to use loops and define at least one function to achieve this!

Exercise: Write fizz buzz using a function, taking a parameter for the max.

Good luck. Come back here when you've completed that.