Zig, Rust, and Other Languages
Zig’s allocation model and “no hidden allocations”
- Several comments dispute the article’s strong claim that Zig avoids hidden allocations.
- Standard C functions mostly do not allocate;
strdupis a notable exception. - In Zig, most stdlib APIs follow the “pass an allocator if this might allocate” convention, but not all:
std.Thread.spawnallocates (stack + heap for argument payload) without an explicit allocator.std.ArrayListstores an allocator internally, so method calls can allocate even when no allocator is passed.ArrayListUnmanagedexists to keep allocators at a higher level and make allocations explicit.
- Some argue this is “just a convention” rather than a strict guarantee; others say that’s still valuable.
Memory management trade‑offs across languages
- Nim is highlighted as a systems language with configurable memory management; default ARC is seen as more ergonomic than threading allocators through Zig code.
- Counterpoint: one can use a global allocator or attach allocators to objects in Zig to avoid excessive plumbing.
- Odin, C with good APIs and arenas, and others are cited to argue that API design matters more than language per se.
Standard library size vs ecosystem fragmentation
- One camp prefers compact stdlibs to avoid C++‑style bloat, enable faster evolution, and reduce long‑term maintenance of obsolete APIs.
- Another camp argues small stdlibs force reliance on many third‑party packages, leading to fragmentation, multiple competing libraries, and dependency hell.
- Examples:
- Python: large stdlib is generally seen as positive, though some modules are outdated; popular third‑party libs (e.g., HTTP clients) still win on ergonomics.
- Go: praised stdlib but specific parts (logging, flags, earlier
net.IP) are criticized; newer abstractions likenetipimprove things. - Rust: absence of compression in stdlib is defended as keeping evolving domains in crates; others point to good compressors in other ecosystems’ stdlibs as counter‑evidence.
- Suggested compromise: small core stdlib + officially maintained “blessed” packages, or later adoption of de‑facto standards.
Package managers and dependency concerns
- Zig’s package story:
- Has package management via
build.zig.zonand git references; upcoming 0.12 improvements are anticipated. - No central package repository by design (similar to Go); some see this as safer, others as a bad decision.
- Has package management via
- General concerns:
- Multiple competing C/C++ package managers (vcpkg, conan, etc.) don’t interoperate well.
- Rust’s
cargo:- Avoids per‑project duplication of sources; dead code elimination mitigates binary bloat.
- Problems cited: large caches and stale incremental artifacts; upcoming automatic cache GC on nightly is welcomed.
- Some suggest using Nix instead of language‑specific managers.
Strings, Unicode, and type‑system guarantees
- Zig:
- Uses
[]const u8for strings; by convention these are UTF‑8. - Functions often assume valid UTF‑8 without runtime checks; responsibility lies with the producer.
- Critics liken this to “just don’t write bugs” and argue for encoding invariants in types.
- Uses
- Rust:
- Distinguishes
String(owned UTF‑8) and&str(borrowed UTF‑8), with runtime UTF‑8 validation in safe code. - Unsafe constructors allow skipping checks only when the programmer promises validity.
- Separate types like
OsStringavoid forcing UTF‑8 where it’s not guaranteed. - This model is praised for safety and flexibility but criticized for complexity and learning overhead.
- Distinguishes
- Go and others:
- Go
stringis “just bytes”; can hold arbitrary data, not guaranteed UTF‑8.
- Go
- Unicode support:
- Zig’s
std.unicodecovers validation and codepoint iteration; more advanced support (graphemes, categories) is in external libraries. - Similar gaps exist in Rust and Go; full Unicode handling (e.g., grapheme iteration, locale‑aware sorting) is complex and often pushed to libraries.
- Zig’s
- Some argue that because “string” requirements are so varied (mutability, slicing, Unicode semantics, performance), it’s natural that ecosystems grow multiple string abstractions despite a built‑in type.