# Public Declarations

### Public Declarations

A Zig program may be split across many files. Declarations can be made visible outside a file with `pub`.

Here is a small file named `math.zig`:

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

The function is declared with:

```zig
pub fn
```

which means the declaration is public.

Another file may import and use it:

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

pub fn main() void {
    const n = math.square(5);

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

The output is:

```text
25
```

The declaration:

```zig
const math = @import("math.zig");
```

imports the file and binds it to the name `math`.

The function is called with:

```zig
math.square(5)
```

The dot selects a declaration from the imported file.

Declarations without `pub` are private:

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

This function may only be used inside its own file.

The following file is valid:

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

pub fn compute(x: i32) i32 {
    return helper(x) * 2;
}
```

`compute` is public. `helper` is private implementation detail.

This is a common pattern.

A file in Zig acts much like a namespace. Public declarations form the visible interface.

Variables may also be public:

```zig
pub const version = "0.16";
```

Another file may access it:

```zig
const config = @import("config.zig");

const v = config.version;
```

Types may be public too:

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

The imported type is used normally:

```zig
const geometry = @import("geometry.zig");

const p = geometry.Point{
    .x = 3,
    .y = 4,
};
```

The name after `pub` becomes part of the module interface.

Good interfaces expose only what users need.

This file exposes too much:

```zig
pub fn parse() void {}
pub fn scan() void {}
pub fn tokenize() void {}
pub fn internalBuffer() void {}
pub fn tempState() void {}
```

Internal details become difficult to change later.

A better design hides implementation details:

```zig
fn scan() void {}
fn tokenize() void {}

pub fn parse() void {
    scan();
    tokenize();
}
```

Only the high-level operation is public.

Public declarations also affect documentation and discoverability. A clean public interface makes libraries easier to understand.

Imports are resolved at compile time. Zig does not have a separate header language like C.

The file itself defines both implementation and interface.

This keeps declarations synchronized. There is no separate header file that can drift out of date.

Circular imports should generally be avoided:

```text
a.zig imports b.zig
b.zig imports a.zig
```

This often indicates poor structure.

Instead, move shared declarations into a third file.

Public declarations are commonly grouped near the top of a file:

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

pub fn distance() void {}

fn helper() void {}
```

The public interface becomes easy to find.

Exercise 4-13. Create a file `math.zig` with public functions `add` and `sub`.

Exercise 4-14. Add a private helper function used by one of the public functions.

Exercise 4-15. Create a public struct `Person` with fields `name` and `age`.

Exercise 4-16. Why might exposing too many public declarations make a library harder to maintain?

