Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Fine, but there's a noticeable asymmetry in how the three languages get treated. Go gets dinged for hiding memory details from you. Rust gets dinged for making mutable globals hard and for conceptual density (with a maximally intimidating Pin quote to drive it home). But when Zig has the equivalent warts they're reframed as virtues or glossed over.

Mutable globals are easy in Zig (presented as freedom, not as "you can now write data races.")

Runtime checks you disable in release builds are "highly pragmatic," with no mention of what happens when illegal behavior only manifests in production.

The standard library having "almost zero documentation" is mentioned but not weighted as a cost the way Go's boilerplate or Rust's learning curve are.

The RAII critique is interesting but also somewhat unfair because Rust has arena allocators too, and nothing forces fine-grained allocation. The difference is that Rust makes the safe path easy and the unsafe path explicit whereas Zig trusts you to know what you're doing. That's a legitimate design, hacking-a!

The article frames Rust's guardrails as bureaucratic overhead while framing Zig's lack of them as liberation, which is grading on a curve. If we're cataloging trade-offs honestly

> you control the universe and nobody can tell you what to do

...that cuts both ways...





I pretty new to Rust and I’m wondering why global mutables are hard?

At first glance you can just use static variable of a type supporting interior mutability - RefCell, Mutex, etc…


> I pretty new to Rust and I’m wondering why global mutables are hard?

They're not.

  fn main() {
      unsafe {
          COUNTER += 1;
          println!("COUNTER = {}", COUNTER);
      }
  
      unsafe {
          COUNTER += 10;
          println!("COUNTER = {}", COUNTER);
      }
  }
Global mutable variables are as easy in Rust as in any other language. Unlike other languages, Rust also provides better things that you can use instead.

People always complain about unsafe, so I prefer to just show the safe version.

  use std::sync::Mutex;

  static LIST: Mutex<Vec<String>> = Mutex::new(Vec::new());

  fn main() -> Result<(), Box<dyn std::error::Error>> {

      LIST.lock()?.push("hello world".to_string());
      println!("{}", LIST.lock()?[0]);

      Ok(())
  }

This is completely different from the previous example.

It doesn't increment anything for starters. The example would be more convoluted if it did the same thing.

And strings in rust always delivers the WTFs I need o na Friday:

    "hello world".to_string()

    use std::sync::Mutex;
    fn main() -> Result<(), Box<dyn std::error::Error>> {
        static PEDANTRY: Mutex<u64> = Mutex::new(0);
        *PEDANTRY.lock()? += 1;
        println!("{}", PEDANTRY.lock()?);
        Ok(())
    }

Still different. Yours only increments once. Doesn't pass basic QA.

And declaring a static variable inside a function, even if in main, smells.


OP you keep comparing to doesn't even declare the variable. I'm done with you.

OP here, not showing how to declare the variable was an oversight on my part.

  static mut COUNTER: u32 = 0;
(at top-level)

If on 2024 edition, you will additionally need

  #![allow(static_mut_refs)]

Yup, your example was fine, as I said I just wanted to show a safe method too :-)

That is correct. Kinda. Refcell can not work because Rust considers globals to be shared by multiple threads so requires thread safety.

And that’s where a number of people blow a gasket.


A second component is that statics require const initializers, so for most of rust’s history if you wanted a non-trivial global it was either a lot of faffing about or using third party packages (lazy_static, once_cell).

Since 1.80 the vast majority of uses are a LazyLock away.


I don't think it's specifically hard, it's more related to how it probably needed more plumbing in the language that authors thought would add to much baggage and let the community solve it. Like the whole async runtime debates



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: