Live data from Hacker News

Thoughts on Go vs. Rust vs. Zig

sinclairtarget.com

221–230 of 599 posts

Re: Thoughts on Go vs. Rust vs. Zig

#221

Earlier quoted context omitted.

> Go programmer attitude is "do what I said, and trust that I read the library docs before I said it". I agree and think Go gets unjustly blamed for some things: most of the foot guns people say Go has are clearly laid out in the spec/documentation. Are these surprising behaviors or did you just not read? Getting a compiler and just typing away is not a great way of going about learning things if that compiler is not…

It's not unjust to blame the tool if it behaves contrary to well established expectation, even if that's documented - it's just poor ergonomics then.

“Clearly it’s your fault for not realising that we embedded razor blades in our hammers! What did you think, that you could safely pick up a tool?”

Re: Thoughts on Go vs. Rust vs. Zig

#222
post #214
post #29

> In Rust, creating a mutable global variable is so hard that there are long forum discussions on how to do it. In Zig, you can just create one, no problem. Well, no, creating a mutable global variable is trivial in Rust, it just requires either `unsafe` or using a smart pointer that provides synchronization. That's because Rust programs are re-entrant by default, because Rust provides compile-time thread-safety. If…

> [...] is trivial in Rust [...] it just requires [...] This is a tombstone-quality statement. It's the same framing people tossed around about C++ and Perl and Haskell (also Prolog back in the day). And it's true, insofar as it goes. But languages where "trivial" things "just require" rapidly become "not so trivial" in the aggregate. And Rust has jumped that particular shark. It will never be trivial, period.

> languages where "trivial" things "just require" rapidly become "not so trivial" in the aggregate

Sure. And in C and Zig, it's "trivial" to make a global mutable variable, it "just requires" you to flawlessly uphold memory access invariants manually across all possible concurrent states of your program.

Stop beating around the bush. Rust is just easier than nearly any other language for writing concurrent programs, and it's not even close (though obligatory shout out to Erlang).

Re: Thoughts on Go vs. Rust vs. Zig

#223
post #104

Earlier quoted context omitted.

> Async Rust is the ugliest and least readable language I've ever seen and I've done a lot of heavily templated C++ No, this is a wild claim that shows you've either never written async Rust or never written heavily templated C++. Feel free to give code examples if you want to suggest otherwise.

Every language i am not deeply familiar with is disgusting. But for real the ratings for me stem from how much arcane symbology i must newly memorize. I found rust to be up there but digestible. The thought of c++ makes me want to puke but not over the syntax.

  template
  concept non_zero = (V != 0);

  template
  concept arithmetic = std::is_arithmetic_v;

  template
  requires non_zero
  struct complicated {
      template
      using nested_alias = std::tuple...,
          std::conditional_t 0 && ...), T, std::nullptr_t>
      >;

      template
      static constexpr auto process() {
          return [](std::index_sequence) {
              return nested_alias{};
          }(std::make_index_sequence{});
      }
  };
I most definitely agree.

Re: Thoughts on Go vs. Rust vs. Zig

#224
post #222
post #214

Earlier quoted context omitted.

> [...] is trivial in Rust [...] it just requires [...] This is a tombstone-quality statement. It's the same framing people tossed around about C++ and Perl and Haskell (also Prolog back in the day). And it's true, insofar as it goes. But languages where "trivial" things "just require" rapidly become "not so trivial" in the aggregate. And Rust has jumped that particular shark. It will never be trivial, period.

> languages where "trivial" things "just require" rapidly become "not so trivial" in the aggregate Sure. And in C and Zig, it's "trivial" to make a global mutable variable, it "just requires" you to flawlessly uphold memory access invariants manually across all possible concurrent states of your program. Stop beating around the bush. Rust is just easier than nearly any other language for writing concurrent programs,…

This is a miscommunication between the values of “shipping” which optimizes for fastest time to delivery and “correctness” which optimizes for the quality of the code.

Rust makes it easy to write correct software quickly, but it’s slower for writing incorrect software that still works for an MVP. You can get away with writing incorrect concurrent programs in other languages… for a while. And sometimes that’s what business requires.

I actually wish “rewrite in Rust” was a more significant target in the Rust space. Acknowledging that while Rust is not great for prototyping, the correctness/performance advantages it provides justifies a rewrite for the long-term maintenance of software—provided that the tools exist to ease that migration.

Re: Thoughts on Go vs. Rust vs. Zig

#225

> it is like C in that you can fit the whole language in your head. This is exactly why I find Go to be an excellent language. Most of the times, Go is the right tool. Rust doesn't feel like a tool. Ceremonial yet safe and performant.

> it is like C in that you can fit the whole language in your head.

Sure, you can fit all of C in your head, including all the obscure footguns that can lead to UB: https://gist.github.com/Earnestly/7c903f481ff9d29a3dd1

And other fun things like aliasing rules and type punning.

Re: Thoughts on Go vs. Rust vs. Zig

#226

Earlier quoted context omitted.

>> In Go and Rust and so many other languages, you tend to allocate little bits of memory at a time for each object in your object graph. Your program has thousands of little hidden malloc()s and free()s, and therefore thousands of different lifetimes. > Rust can also do arena allocations, and there is an allocator concept in Rust, too. There's just a default allocator, too. Thank you. I've seen this repeated so many…

"Batch allocation" in Rust is just a matter of Box-ing a custom-defined tuple of objects as opposed to putting each object in its own little Box. You can even include MaybeUninit's in the tuple that are then initialized later in unsafe code, and transmuted to the initialized type after-the-fact. You don't need an allocator library at all for this easy case, that's more valuable when the shape of allocations is in fac…

> You don't need an allocator library at all for this easy case, that's more valuable when the shape of allocations is in fact dynamic.

Though I'd still reach for something like Bumpalo ( https://crates.io/crates/bumpalo ) unless I had good reason to avoid it.

Re: Thoughts on Go vs. Rust vs. Zig

#227
post #177

Earlier quoted context omitted.

No, this is still misunderstanding. Overcommit means that the act of memory allocation will not report failure, even when the system is out of memory. Instead, failure will come at an arbitrary point later, when the program actually attempts to use the aforementioned memory that the system falsely claimed had been allocated. Allocating all at once on startup doesn't help, because the program can still fail later when…

Which is why I said "allocate and pin ". POSIX systems have mlock()/mlockall() to prefault allocated memory and prevent it from being paged out.

Aha, my apologies, I overlooked that.

Re: Thoughts on Go vs. Rust vs. Zig

#228
post #76

I think the Go part is missing a pretty important thing: the easiest concurrency model there is. Goroutines are one of the biggest reasons I even started with Go.

I'll disagree with you there. Structured concurrency is the easiest concurrency model there is: https://vorpus.org/blog/notes-on-structured-concurrency-or-g...

Re: Thoughts on Go vs. Rust vs. Zig

#229
post #69

Earlier quoted context omitted.

let mut file = File::create("foo.txt").context("failed to create file")?; Of all the things I find hard to understand in Rust, this isn't one of them.

What's the "?" doing? Why doesn't it compile without it? It's there to shortcut using match and handling errors and using unwrap, which makes sense if you know Rust, but the verbosity of go is its strength, not a weakness. My belief is that it makes things easier to reason about outside of the trivial example here.

> What's the "?" doing? Why doesn't it compile without it?

I don't understand this line of thought at all. "You have to learn the language's syntax to understand it!"...and so what? All programming language syntax needs to be learned to be understood. I for one was certainly not born with C-style syntax rattling around in my brain.

To me, a lot of the discussion about learning/using Rust has always sounded like the consternation of some monolingual English speakers when trying to learn other languages, right down to the "what is this hideous sorcery mark that I have to use to express myself correctly" complaints about things like diacritics.

Post reply on HN