typestar

Language basics

27 steps in 9 sets of Zig.

Zig is a modern systems language with an old-fashioned promise: no hidden control flow, no hidden allocations, no preprocessor — what the code says is what the machine does. Andrew Kelley started it in 2015 as a better C rather than a bigger C++, and it has grown a devoted following for exactly that restraint, plus a compiler that cross-compiles to anywhere almost as an afterthought.

This tour covers the core as zig 0.16 compiles it: const and var under a compiler that rejects unused code, exhaustive switch, the loop forms, errors as values with try and catch, optionals with orelse, pointers and slices, structs and enums and tagged unions, comptime and the generics that fall out of it, explicit allocators from DebugAllocator to arenas, and the std.mem and std.fmt toolboxes. The encore ships complete programs. Every seed compiles and runs — and in Zig, compiling is a high bar.

Start this tour

Values

  • The program shapeThe smallest Zig program: one import, a public main, two prints.
  • const and varZig polices both directions: const cannot change, var must.
  • Integer widthsThe width is part of the type: u8 and i32, u64 — and u3 if three bits is what you mean.

Control flow

  • if and switchBoth branch forms produce values, and switch must account for every case.
  • while loopsThe while loop with a continue expression, and one that breaks with a value.
  • for loopsfor walks elements; add 0.. and it hands you the index too.

Errors

  • Errors and tryErrors are values in the return type: a vault that either opens or says why not.
  • catch and orelseTwo fallback operators: catch for error unions, orelse for optionals.
  • deferCleanup declared next to the thing it cleans: defer runs at scope exit, in reverse.

Optionals & pointers

  • Optionals?u32 is a berth number or null, and the compiler will not let you forget which.
  • PointersA single-item pointer doubles a counter in place; .* is the dereference.
  • SlicesA slice is a pointer plus a length onto memory that already exists.

Structs & enums

  • StructsA kayak struct with field defaults and a method that reads naturally.
  • EnumsA cargo enum with its own method, exhaustively switched.
  • Tagged unionsOne reading, two shapes: a float when the sensor works, a reason when it does not.

comptime

  • comptimeThe same language runs at compile time: a Fibonacci number baked into the binary.
  • GenericsA generic is a function that takes a type: one largest() for ints and floats.
  • Builtins and castsThe @-builtins: reflection on types, and casts that are always spelled out.

Memory

  • AllocatorsNothing allocates behind your back: rent bytes from an allocator, free them, get audited.
  • ArrayListThe growable list is unmanaged: every append hands the allocator in explicitly.
  • Arena allocationFive allocations, zero frees: the arena returns everything in one deinit.

The standard library

  • std.memStrings are []const u8, and std.mem is the toolbox that works them.
  • std.fmtFormat into a stack buffer and parse back out — no allocator in sight.
  • StringHashMapA harbor registry: string keys, integer berths, and an iterator over the keys.

Encore

  • word_freq.zigA word-frequency table from tokenize, a hash map, a sort, and a bar chart.
  • grade_report.zigQuiz scores fold into averages and letter grades, then a formatted class report.
  • temp_stats.zigA week of daily highs reduced to low, high and mean, with a scaled bar per day.

The other Zig tours