Crabtime: Zig’s Comptime in Rust
Crabtime’s Purpose and Ergonomics
- Many commenters like Crabtime’s idea: writing mostly normal Rust to generate code, instead of wrestling with
macro_rules!or full proc-macro token trees. - People report replacing complex declarative macros with Crabtime and finding the result more readable, maintainable, and customizable (e.g., generating benchmark functions, reading files at compile time).
- There is interest but limited real‑world usage so far; the crate is quite new and depends on the usual proc-macro stack (
syn,quote,proc-macro2, plus small extras).
Not “Zig comptime”
- Multiple commenters argue Crabtime is not equivalent to Zig’s
comptime:- Rust macros lack compile-time reflection and first-class type values.
- Zig’s comptime is staged evaluation of ordinary functions that can construct types and values directly, rather than syntax‑level rewriting.
- Crabtime still fundamentally operates as Rust macros do (token generation), so it can’t bridge that semantic gap.
- Some call the crate’s “Zig’s comptime in Rust” positioning misleading or at least aspirational.
Rust const fn, const blocks, and compile-time behavior
- Discussion clarifies that Rust has
const fnand const contexts that run at compile time, but:const fnmust also be valid at runtime and produce (essentially) the same results, greatly restricting side effects and environment access.- Zig comptime functions aren’t constrained by runtime semantics in the same way; types are first‑class compile‑time values.
- There is a side thread on floating‑point semantics in const contexts, cross‑compilation, and NaN behavior, noting recent stabilization work.
Generics, templates, and reflection
- Long debate compares:
- Zig’s comptime-as-generics versus C++ templates and Rust generics/traits.
- Whether comptime alone can replace features like generics, concepts/traits, macros, and conditional compilation.
- One side argues comptime unifies many mechanisms into one simple construct; critics counter that:
- It’s more template‑like than a full parametric type system.
- Lacks explicit constraints/interfaces (like Rust traits or C++ concepts).
- Cannot fully replace macros or trait systems, especially for static checking and IDE support.
Macros, tooling, and code navigation
- Several people dislike macros because they:
- Break “go to definition” and simple grep/search, especially when identifiers are concatenated or types are created via macros.
- Are harder to debug than normal code; proc-macro debugging often degrades to panicking with debug strings.
- Crabtime is praised for letting you construct strings and structures in Rust and inject them, which helps understandability, though identifier concatenation remains problematic for searchability.
Security and sandboxing
- Concern is raised that Rust proc macros can run arbitrary code at compile time and thus pose a supply‑chain risk once Rust is widely adopted.
- Others note this problem exists in many build systems (any build script can “pwn” you), and mention experimental approaches to sandboxing macros via WebAssembly, but this is not yet a built‑in, robust solution.
Broader language‑design themes
- The thread broadens into:
- Rust vs Zig tradeoffs: Rust’s stronger safety and type system vs Zig’s simplicity and powerful comptime; claims that each can’t easily adopt the other’s strengths without becoming a different language.
- Comparisons with C++ (templates,
constexpr, concepts, upcoming reflection) and older systems languages, arguing over what is genuinely “novel”.
- Some readers express feeling lost or underqualified amid the deep PL discussions; others dismiss comptime/macros as crutches compared to dependently typed or more expressive functional languages.