Targets · Zig · Naming considerations

Naming considerations

A Program name nests to any depth — Ui.Button.Integer.Increment. This page is how that dotted name is carried into Zig, which nests just as deeply.

Contents

How a Program becomes Zig, in parts. Start with the introduction, then follow each part into the rendered output and the runtime it links against.

How it looks

Zig keeps the full path, lowercased to snake_case and joined with a dot — the same separator as Program.

ui.button.integer.increment(count, struct { pub fn run() void { … } }.run);   // was Ui.Button.Integer.Increment

The natural idiom

In Zig a struct is also a namespace: a pub const can hold nested pub const structs and pub fns, and files are structs too. So nesting a container inside a container is exactly idiomatic — nothing has to be faked. The only difference from Program is the snake_case convention on the segments.

Keeping the real dotted name

Each namespace segment becomes a nested container (pub const … = struct { … }, or an imported file of that name), and the leaf a pub fn inside it — so the path is a genuine, compiler-resolved member chain, every level real.

pub const ui = struct {
  pub const button = struct {
    pub const integer = struct {
      pub fn increment(count: ReactiveValue(i64), body: fn () void) void { … }
    };
  };
};

// the call is the Program name, snake_cased:
ui.button.integer.increment(count, struct { pub fn run() void { … } }.run);

A record TYPE is a struct, a union TYPE a union(enum); a built-in value type folds to a native type (Maths.Integeri64).

Recommendation

Use nested struct containers. Zig keeps every level of the name real, with a real dot for the separator — the closest of all the targets to Program's own notation, alongside Swift and Rust (which uses ::), and unlike Dart and Go, which must join with an underscore. The only identifiers ever rewritten are ordinary names that collide with a reserved word.