# What Is Zig

### What Is Zig

Zig is a programming language for writing programs that are fast, clear, and close to the machine.

A computer does not understand words like `print`, `main`, or `if`. It understands machine instructions. A programming language gives us a way to write instructions in a form humans can read. Then a compiler turns those instructions into a program the computer can run.

Zig is a compiled language. You write Zig source code in a text file. The Zig compiler reads that file, checks it, and produces an executable program.

A tiny Zig program looks like this:

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

pub fn main() void {
    std.debug.print("Hello, Zig!\n", .{});
}
```

This prints:

```text
Hello, Zig!
```

The program has three important parts.

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

This imports Zig’s standard library. The standard library contains useful code for printing text, working with files, handling memory, using data structures, and many other common tasks. The name `std` is short for “standard.”

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

This defines the function where the program begins. The name `main` is special. When you run the program, Zig starts there.

The word `fn` means “function.” A function is a named block of code.

The word `void` means this function does not return a value.

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

This prints text to the screen. The `\n` means “new line.” The `.{}` part is an empty list of values to format into the text.

At first, this syntax may look strange. That is normal. The goal now is not to memorize every symbol. The goal is to see the basic shape of a Zig program.

#### Zig Is a Systems Programming Language

Zig is often used for systems programming.

Systems programming means writing software that works close to the operating system, memory, files, hardware, or network. Examples include:

| Program type | Example |
|---|---|
| Command-line tool | A program you run from the terminal |
| Server | A program that handles network requests |
| Database | A program that stores and reads data efficiently |
| Game engine | A program that needs fast graphics and memory control |
| Operating system code | Code that talks directly to hardware |
| Compiler | A program that translates source code into machine code |

C has been used for this kind of work for decades. Zig can do many of the same jobs, but with a more modern design.

Zig gives you control over memory, data layout, build settings, and machine-level behavior. It does not hide these things from you.

#### Zig Is Explicit

One of Zig’s main ideas is explicitness.

In Zig, important things are usually visible in the code.

If a function can fail, its type shows that.

```zig
fn readFile() !void {
    // This function may return an error.
}
```

The `!void` means the function either succeeds and returns `void`, or fails with an error.

If a function needs memory allocation, it often receives an allocator directly.

```zig
fn makeBuffer(allocator: std.mem.Allocator) ![]u8 {
    return try allocator.alloc(u8, 100);
}
```

This tells us that the function needs memory and that allocation can fail.

Zig does not try to make everything look easy by hiding important details. Instead, it makes the details visible so you can reason about them.

That is one of the first lessons of Zig: clear code is more important than magical code.

#### Zig Has No Garbage Collector

Many languages manage memory automatically with a garbage collector. A garbage collector finds memory that is no longer used and frees it later.

Zig does not use a garbage collector by default.

This means you usually decide when and how memory is allocated. That gives you more control. It also means you must think carefully about ownership and lifetime.

For beginners, this may sound scary. But Zig’s style helps by making allocation visible.

When you see an allocator in a function, you know memory may be created there. When you see cleanup code, you know memory is being released.

Example:

```zig
const data = try allocator.alloc(u8, 100);
defer allocator.free(data);
```

The first line allocates 100 bytes.

The second line says to free that memory when the current scope ends.

The word `defer` means “run this later, when we leave this scope.” It is commonly used for cleanup.

#### Zig Has Errors Instead of Exceptions

Some languages use exceptions for errors. An exception can jump out of one function and travel through many layers of code.

Zig does not use exceptions.

In Zig, errors are values. You return them. You handle them. You can see them in the function type.

For example:

```zig
fn divide(a: i32, b: i32) !i32 {
    if (b == 0) {
        return error.DivisionByZero;
    }

    return a / b;
}
```

This function returns either an `i32` result or an error.

A caller can use `try`:

```zig
const result = try divide(10, 2);
```

This means: call `divide`. If it succeeds, store the result. If it fails, return the error from the current function.

This makes error handling direct and visible.

#### Zig Has Compile-Time Code

Zig has a powerful feature called `comptime`.

`comptime` means “compile time.” It lets Zig run some code while the program is being compiled.

This is useful because some decisions can be made before the program runs.

Here is a simple example:

```zig
fn add(comptime T: type, a: T, b: T) T {
    return a + b;
}
```

This function works with different types:

```zig
const x = add(i32, 10, 20);
const y = add(f64, 1.5, 2.5);
```

The type `T` is known at compile time. Zig uses that type to generate the correct version of the function.

This gives Zig a clean way to write generic code without a separate macro language.

#### Zig Works Well with C

Zig is designed to work well with C.

This matters because much of the world’s low-level software is written in C. Operating system APIs, graphics libraries, database libraries, compression libraries, and many old but important tools expose C interfaces.

Zig can call C code. Zig can include C headers. Zig can also compile C code.

For example, Zig provides:

```bash
zig cc
```

This lets Zig act like a C compiler.

That makes Zig useful even in projects that are not fully written in Zig. You can use Zig beside C instead of replacing everything at once.

#### Zig Is Small in Spirit

Zig does not try to include every possible feature.

It avoids classes, inheritance, exceptions, hidden allocation, and complicated runtime behavior. Instead, it gives you a smaller set of tools and expects you to use them clearly.

The language focuses on:

| Idea | Meaning |
|---|---|
| Explicit control | Important behavior should be visible |
| Manual memory management | You choose how memory is allocated and freed |
| Strong compile-time checks | Many mistakes are caught before running |
| Simple error handling | Errors are returned as values |
| C compatibility | Existing C code can be reused |
| Compile-time programming | Some logic can run during compilation |

This makes Zig feel different from languages like Python, JavaScript, Java, or Go.

Zig asks you to be precise. In return, it gives you more control.

#### What You Should Remember

Zig is a compiled systems programming language.

It is designed for programs where speed, memory, reliability, and control matter.

It has no hidden garbage collector. It has no exceptions. It makes errors, memory, and types visible in the code.

At the beginning, Zig may feel strict. That strictness is part of the design. The compiler is trying to help you catch mistakes early and understand exactly what your program does.

