# Functions

> Immutable parameters and explicit discards.

```zig
const std = @import("std");
const expect = std.testing.expect;

fn addFive(x: u32) u32 {
    // Parameters are const. `x += 5` here would not compile.
    return x + 5;
}

fn fibonacci(n: u16) u16 {
    if (n == 0 or n == 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

test "calling a function" {
    const y = addFive(0);
    try expect(@TypeOf(y) == u32);
    try expect(y == 5);
}

test "recursion" {
    try expect(fibonacci(10) == 55);
}

test "values must be used" {
    // Zig has no unused-value warning because it is an error. `_ =` is the
    // explicit way to discard something.
    _ = addFive(1);
}
```

*Runnable: compiled to WebAssembly and executed by CI against Zig master. (`02-language.functions`)*

## Parameters are constant

Function parameters are immutable. This does not compile:

```zig
fn addFive(x: u32) u32 {
    x += 5;      // error: cannot assign to constant
    return x;
}
```

If you want a mutable local, make one. The benefit is that a parameter always
means what it meant at the call site, all the way down the function body.

## Unused values are errors

Zig has no "unused variable" *warning*, because it is an error. Discarding is
explicit:

```zig
_ = addFive(1);
```

This sounds pedantic until you realise it catches the case where you called a
function for a result you then forgot to use.

## Recursion and the stack

`fibonacci` above recurses happily, but Zig cannot always prove a bound on
stack usage. For deep or input-driven recursion, an explicit stack or an
iterative formulation is the safer choice: there is no automatic tail-call
guarantee to lean on.
