# Exercises

### Exercises

1. Write a program that computes several Fibonacci numbers with `comptime`. Print the results at runtime.

2. Rewrite this declaration so the value is computed during compilation:

```zig
const x = 10 * 20;
```

3. Explain why this code is invalid:

```zig
var n: usize = 4;
const a = comptime n * 2;
```

4. Write a function:

```zig
fn square(x: i32) i32
```

Call it both at runtime and with `comptime`.

5. Write a generic function:

```zig
fn zero(comptime T: type) T
```

Return the zero value of the given type.

6. Write a generic function:

```zig
fn max(comptime T: type, a: T, b: T) T
```

Test it with integers and floating-point values.

7. Write a function:

```zig
fn Array(comptime T: type, comptime N: usize) type
```

Return the type `[N]T`.

8. Write a function:

```zig
fn Pair(comptime T: type) type
```

Return a struct with fields `first` and `second`.

9. Add methods `swap` and `print` to the type returned by `Pair`.

10. Write a function:

```zig
fn Buffer(comptime N: usize) type
```

The returned type should contain:

```zig
data: [N]u8
len: usize
```

11. Add methods `append` and `clear` to `Buffer`.

12. Write a function:

```zig
fn isInteger(comptime T: type) bool
```

Use `@typeInfo`.

13. Write a function:

```zig
fn isFloat(comptime T: type) bool
```

Use `@typeInfo`.

14. Write a function that prints the names and sizes of these types:

```zig
u8
u16
u32
u64
```

Use `inline for`.

15. Write an inline loop over this tuple:

```zig
.{ 10, true, "zig" }
```

Print each value with `{any}`.

16. Write a function:

```zig
fn fieldCount(comptime T: type) usize
```

Return the number of fields in a struct.

17. Write a function:

```zig
fn printFields(comptime T: type) void
```

Print all field names and field types in a struct.

18. Write a function:

```zig
fn enumTagCount(comptime T: type) usize
```

Return the number of tags in an enum.

19. Write a function:

```zig
fn printEnumTags(comptime T: type) void
```

Print all enum tag names.

20. Write a compile-time check that rejects systems where:

```zig
@sizeOf(usize) < 8
```

21. Write a generic stack type:

```zig
fn Stack(comptime T: type, comptime N: usize) type
```

Implement:

* `push`
* `pop`
* `peek`
* `clear`

22. Modify `Stack` so it reports overflow with an error.

23. Write a type generator:

```zig
fn Matrix(comptime T: type, comptime rows: usize, comptime cols: usize) type
```

Store values in:

```zig
[rows][cols]T
```

24. Write a generic function:

```zig
fn swap(comptime T: type, a: *T, b: *T) void
```

25. Write a function:

```zig
fn hasField(comptime T: type, comptime name: []const u8) bool
```

Return whether a struct contains the named field.

26. Write a compile-time assertion that requires a struct to contain a field named `id`.

27. Write a function:

```zig
fn describe(comptime T: type) void
```

Print whether the type is an integer, float, pointer, struct, enum, or union.

28. Write a type generator that returns one struct when a compile-time boolean is true and another when it is false.

29. Explain the difference between:

```zig
for
```

and:

```zig
inline for
```

30. Explain why Zig uses ordinary functions for generic programming instead of a separate template language.

