# The Structure of a Function

### Defining Functions

Functions are reusable blocks of code.

Instead of writing the same logic again and again, you place the logic inside a function and call it whenever you need it.

In Zig, functions are one of the most important building blocks of a program. Every Zig program starts from a function called `main`.

A function can:

- receive input
- perform work
- return a result

A simple function looks like this:

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

This defines a function named `sayHello`.

Let us break it apart carefully.

## The Structure of a Function

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

Each piece has meaning.

| Part | Meaning |
|---|---|
| `fn` | declares a function |
| `sayHello` | function name |
| `()` | parameter list |
| `void` | return type |
| `{}` | function body |

The body contains the code that runs when the function is called.

## Calling a Function

Defining a function does not run it.

You must call it.

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

fn sayHello() void {
    std.debug.print("Hello!\n", .{});
}

pub fn main() void {
    sayHello();
}
```

Output:

```text
Hello!
```

The line:

```zig
sayHello();
```

calls the function.

Execution jumps into the function body, runs the code, then returns back to the caller.

## Why Functions Matter

Functions help organize programs.

Without functions:

```zig
pub fn main() void {
    std.debug.print("Loading file...\n", .{});
    std.debug.print("Parsing file...\n", .{});
    std.debug.print("Saving result...\n", .{});
}
```

As programs grow, everything becomes mixed together.

With functions:

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

fn loadFile() void {
    std.debug.print("Loading file...\n", .{});
}

fn parseFile() void {
    std.debug.print("Parsing file...\n", .{});
}

fn saveResult() void {
    std.debug.print("Saving result...\n", .{});
}

pub fn main() void {
    loadFile();
    parseFile();
    saveResult();
}
```

Now the program is easier to read.

The main function describes the high-level flow of the program.

## Function Names

Function names should describe what the function does.

Good names:

```zig
readFile()
parseJson()
calculateTotal()
sendRequest()
```

Bad names:

```zig
doThing()
stuff()
x()
abc()
```

A good function name reduces mental effort when reading code.

Zig commonly uses camelCase for functions.

## Functions Without Return Values

Some functions only perform actions.

Example:

```zig
fn printBanner() void {
    std.debug.print("=== APP START ===\n", .{});
}
```

The return type is `void`.

`void` means “no value is returned.”

## Functions That Return Values

Functions can also produce values.

Example:

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

This function:

- receives two integers
- adds them
- returns the result

The return type is:

```zig
i32
```

meaning a signed 32-bit integer.

Using the function:

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

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

pub fn main() void {
    const result = add(10, 20);

    std.debug.print("{}\n", .{result});
}
```

Output:

```text
30
```

## Understanding `return`

The `return` keyword immediately exits the function.

Example:

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

Once `return` runs, the function ends.

Any code after it does not execute.

```zig
fn test() i32 {
    return 5;

    // never runs
    return 10;
}
```

Zig detects unreachable code in many situations.

## Parameters

Parameters are inputs to a function.

Example:

```zig
fn greet(name: []const u8) void {
    std.debug.print("Hello, {s}!\n", .{name});
}
```

Here:

```zig
name: []const u8
```

means:

- parameter name: `name`
- parameter type: string slice

Calling it:

```zig
greet("Alice");
greet("Bob");
```

Output:

```text
Hello, Alice!
Hello, Bob!
```

Functions become flexible because parameters allow different input values.

## Multiple Parameters

Functions can accept many parameters.

```zig
fn multiply(a: i32, b: i32, c: i32) i32 {
    return a * b * c;
}
```

Calling:

```zig
const value = multiply(2, 3, 4);
```

Result:

```text
24
```

Parameters are separated by commas.

## Type Checking

Zig checks parameter types strictly.

Example:

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

This works:

```zig
add(1, 2);
```

This fails:

```zig
add("hello", "world");
```

The compiler stops with an error because strings are not integers.

This strictness helps prevent bugs.

## Function Signatures

A function signature describes:

- function name
- parameter types
- return type

Example:

```zig
fn divide(a: f64, b: f64) f64
```

Meaning:

- function name: `divide`
- parameters: two `f64`
- returns: one `f64`

When programmers discuss APIs, they often talk about function signatures.

## Public Functions

Earlier we saw:

```zig
pub fn main() void
```

The word `pub` means public.

Without `pub`, a function is private to the current file.

Example:

```zig
fn helper() void {}
```

Private function.

```zig
pub fn api() void {}
```

Public function.

Most helper functions should remain private unless other files need access.

## Functions as Building Blocks

Large programs are built from many small functions.

Instead of writing one giant function:

```zig
pub fn main() void {
    // 5000 lines
}
```

good programs divide work into smaller pieces:

```zig
loadConfig();
connectDatabase();
startServer();
```

Small functions are:

- easier to test
- easier to debug
- easier to reuse
- easier to understand

## A Complete Example

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

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

fn printResult(value: i32) void {
    std.debug.print("Result: {}\n", .{value});
}

pub fn main() void {
    const result = add(5, 7);

    printResult(result);
}
```

Output:

```text
Result: 12
```

This program already demonstrates an important idea:

- one function computes
- another function prints
- `main` coordinates everything

Each function has a clear responsibility.

## Mental Model

You can think of a function like a machine.

Input goes in:

```text
a, b
```

work happens inside:

```text
a + b
```

output comes out:

```text
result
```

Functions let you package logic into reusable units.

This is one of the foundations of programming, not just in Zig, but in nearly every programming language.

