# Parameters and Return Values

### Parameters and Return Values

Functions communicate through parameters and return values.

Here is a function with one parameter and one return value:

```zig
fn increment(x: i32) i32 {
    return x + 1;
}
```

The parameter is declared inside the parentheses:

```zig
x: i32
```

`x` is the parameter name. `i32` is the parameter type.

The caller passes a value to the function:

```zig
const n = increment(10);
```

Inside the function, `x` receives the value `10`.

Parameters are local to the function. They exist only while the function runs.

Functions may have many parameters:

```zig
fn add(a: i32, b: i32) i32 {
    return a + b;
}
```

The call:

```zig
const x = add(3, 4);
```

passes `3` into `a` and `4` into `b`.

Arguments are matched by position.

The types must agree:

```zig
const x = add(3, 4);
```

but:

```zig
const x = add(true, 4);
```

is an error.

Zig checks argument types at compile time.

A function may return any type:

```zig
fn isPositive(x: i32) bool {
    return x > 0;
}
```

Here the return type is `bool`.

Another example returns a floating-point value:

```zig
fn half(x: f64) f64 {
    return x / 2.0;
}
```

The return type appears after the parameter list:

```zig
fn half(x: f64) f64
```

The `return` statement ends the function immediately:

```zig
fn sign(x: i32) i32 {
    if (x < 0) {
        return -1;
    }

    if (x > 0) {
        return 1;
    }

    return 0;
}
```

Each branch returns a value of the declared return type.

Functions that return nothing use `void`:

```zig
fn newline() void {
    std.debug.print("\n", .{});
}
```

A `void` function may use:

```zig
return;
```

or omit the return statement entirely.

Return values are expressions. The returned value may come from a calculation:

```zig
fn area(width: i32, height: i32) i32 {
    return width * height;
}
```

or from another function call:

```zig
fn square(x: i32) i32 {
    return x * x;
}

fn fourthPower(x: i32) i32 {
    return square(square(x));
}
```

Functions may also return compound values.

This function returns a struct:

```zig
const Point = struct {
    x: i32,
    y: i32,
};

fn makePoint(x: i32, y: i32) Point {
    return Point{
        .x = x,
        .y = y,
    };
}
```

The caller receives the returned value as a normal expression:

```zig
const p = makePoint(3, 4);
```

Parameters themselves are immutable. This is important.

The following is illegal:

```zig
fn f(x: i32) void {
    x = 10;
}
```

because parameters behave like `const`.

If a local mutable value is needed, declare a new variable:

```zig
fn f(x: i32) i32 {
    var y = x;
    y += 1;
    return y;
}
```

This keeps function inputs predictable.

A function signature consists of the function name, parameter types, and return type:

```zig
fn add(a: i32, b: i32) i32
```

The signature describes how the function is used.

Exercise 4-5. Write a function `minimum` that returns the smaller of two integers.

Exercise 4-6. Write a function `clamp` that limits a value to a given range.

Exercise 4-7. Write a function `average` that takes two `f64` values and returns their average.

Exercise 4-8. Why are function parameters immutable in Zig?

