Targets · Rust · 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 Rust, which nests just as deeply.

Contents

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

How it looks

Rust keeps the full path, lowercased to snake_case and joined with :: instead of a dot.

ui::button::integer::Increment(count, Box::new(move || { … }));   // was Ui.Button.Integer.Increment

The natural idiom

Rust modules nest exactly like Program's, so this is the natural idiom — nothing has to be faked. The only cosmetic difference is the separator: Rust uses :: where Program uses ., and module segments are conventionally snake_case.

Keeping the real dotted name

Each namespace segment becomes a nested mod, and the leaf a pub fn inside it, so the path is a genuine, compiler-resolved module chain — every level real.

pub mod ui {
  pub mod button {
    pub mod integer {
      pub fn Increment(count: ReactiveValue<i64>, body: Box<dyn Fn()>) { … }
    }
  }
}

// the call is the Program name, with :: for the dots:
ui::button::integer::Increment(count, Box::new(move || { … }));

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

Recommendation

Use nested mods with ::. Rust keeps every level of the name real, at both the value and the type level, with no compromise beyond the separator — the same as Swift and Zig, 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.