# Defining Functions

### Defining Functions

A function groups statements into a single operation. Functions are the basic unit of organization in a Zig program.

Here is a small function:

```zig
const std = @import("std");

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

pub fn main() void {
    const n = square(5);
    std.debug.print("{d}\n", .{n});
}
```

The output is:

```text
25
```

A function declaration has four parts:

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

`fn` begins the declaration.

`square` is the function name.

`(x: i32)` is the parameter list.

The `i32` after the parameter list is the return type.

The body of the function is enclosed in braces.

The statement:

```zig
return x * x;
```

returns a value to the caller.

Functions may take more than one parameter:

```zig
fn max(a: i32, b: i32) i32 {
    if (a > b) {
        return a;
    }

    return b;
}
```

Parameters are separated by commas. Each parameter has both a name and a type.

Functions that do not return a value use the type `void`:

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

A function call is an expression:

```zig
const x = square(7);
```

The arguments are evaluated, then control passes to the function. When the function returns, the call expression is replaced by the returned value.

Functions may call other functions:

```zig
const std = @import("std");

fn double(x: i32) i32 {
    return x * 2;
}

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

fn compute(x: i32) i32 {
    return square(double(x));
}

pub fn main() void {
    std.debug.print("{d}\n", .{compute(3)});
}
```

The output is:

```text
36
```

Function names follow the same rules as other identifiers. By convention, Zig uses camelCase names:

```zig
fn readFile() void {}
fn parseNumber() void {}
fn printReport() void {}
```

A function can be declared before or after it is used:

```zig
const std = @import("std");

pub fn main() void {
    greet();
}

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

The compiler processes declarations for the whole file, so order usually does not matter.

Local variables belong to the function in which they are declared:

```zig
fn f() void {
    const x = 1;
}

fn g() void {
    // x is not visible here
}
```

The names inside one function are normally hidden from other functions.

A function may contain many return statements:

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

    return x;
}
```

As soon as `return` executes, the function ends.

Small functions are common in Zig. The language encourages programs built from simple pieces with explicit inputs and outputs.

Exercise 4-1. Write a function `cube` that returns the cube of an integer.

Exercise 4-2. Write a function `isEven` that returns `true` if a number is even.

Exercise 4-3. Write a program with three functions: `add`, `sub`, and `mul`.

Exercise 4-4. What happens if a function declares return type `i32` but does not return a value?

