A Rust shaped hole

Language Alternatives to Fill the “Rust-Shaped Hole”

  • Several commenters argue the author’s criteria actually point more to OCaml, Nim, Swift, or Zig than to Rust:
    • OCaml: native, GC’d, expressive; seen as an excellent fit but hampered by a smaller ecosystem and historically weak multithreading.
    • Nim, Odin, Zig, Gleam: each proposed as “Rust without the pain” in different ways; trade-offs are ecosystem maturity, ergonomics, or explicit allocators (Zig).
    • Swift is highlighted repeatedly as an underrated, cross‑platform, memory‑safe, high‑performance alternative with good C/C++ interop and an increasingly decent toolchain.

TypeScript, JS Runtimes, and Native Binaries

  • Several participants share the author’s affection for TypeScript’s type system and abstraction level but see major drawbacks:
    • Native binary story is weak: Bun and Deno can “compile” TS/JS to binaries, but outputs are large (≈60–70MB) and bundle full runtimes.
    • npm ecosystem and tooling configuration (ts-node, ESLint, lints like no-floating-promises) are described as painful and slow on large codebases.
  • There’s interest in “TypeScript-like but compiled” languages:
    • C# is suggested but rejected as too nominal and rigid compared to TS’s unions, literal types, and type manipulation.
    • AssemblyScript, ReasonML, and OCaml are mentioned, but each has gaps in documentation, ecosystem, or TS-like expressiveness.

Rust: Memory Management, Complexity, and Refactoring

  • Strong debate over whether Rust is “manual memory management”:
    • Pro-Rust side: memory is explicitly modeled, but freed automatically via ownership; most code feels closer to automatic management than C’s malloc/free.
    • Critics: the burden moves into the type system and borrow checker; you must choose between ownership, cloning, Rc/Arc, RefCell, etc., which is perceived as complexity.
  • Many report Rust makes large refactors easier:
    • Changing types and ownership patterns lets the compiler point out all required updates; if it compiles, memory and thread-safety invariants are likely preserved.
  • Others find Rust more difficult than C or Haskell in practice, citing:
    • Lifetimes, closure traits (Fn/FnOnce), trait resolution, macros, and the need to pull in many crates for basic tasks.
    • Perception that Rust rivals C++ in complexity, though defenders argue Rust’s complexity is more principled and better supported by tooling and error messages.

C, C++, and “Simplicity” Debated

  • The article’s claim that C is simple and easy to review is heavily contested:
    • Commenters point to undefined behavior, data races, null propagation, aliasing with restrict, and global state as “spooky action at a distance.”
    • Annex J.2’s long UB list is cited as evidence that C’s apparent syntactic simplicity hides deep semantic fragility.
  • C++ is widely seen as more complex than Rust due to decades of backwards compatibility, multiple initialization modes, template and move-semantics intricacies, and a “hoarder’s house” of overlapping features.

Performance, GC, and “Solid” Native Programs

  • Some argue GC’d languages (Java, Go, Haskell) can achieve competitive or superior throughput, especially when allowed large heaps; tracing GCs are framed as converting RAM into speed.
  • Others emphasize memory footprint, predictability, and fewer runtime dependencies as reasons to prefer native, statically linked binaries (Rust, Go, Swift), which “feel solid” by depending mainly on the OS kernel rather than external runtimes or shared libraries.

Miscellaneous Technical Points

  • The article’s RAM-latency analogy (days vs minutes) is dissected; several posts clarify the distinction between latency and throughput and caution against mixing them in metaphors.
  • Go’s “simplicity” is criticized as pushing complexity into application code (especially error handling), whereas Rust and some ML-family languages encode more invariants in types at the cost of a steeper learning curve.