Live data from Hacker News

Thoughts on Go vs. Rust vs. Zig

sinclairtarget.com

111–120 of 599 posts

Re: Thoughts on Go vs. Rust vs. Zig

#111
post #60

> In Go, a slice is a fat pointer to a contiguous sequence in memory, but a slice can also grow, meaning that it subsumes the functionality of Rust’s Vec type and Zig’s ArrayList. Well, not exactly. This is actually a great example of the Go philosophy of being "simple" while not being "easy". A Vec has identity; the memory underlying a Go slice does not. When you call append(), a new slice is returned that may or ma…

Writing "append(s, ...)" instead of "s = append(s, ...)" results in a compiler error because it is an unused expression. I'm not sure how a newbie could make this mistake since that code doesn't compile.

Re: Thoughts on Go vs. Rust vs. Zig

#112

> Other features common in modern languages, like tagged unions or syntactic sugar for error-handling, have not been added to Go. > It seems the Go development team has a high bar for adding features to the language. The end result is a language that forces you to write a lot of boilerplate code to implement logic that could be more succinctly expressed in another language. Being able to implement logic more succinct…

What is the context that the Go code adds here? When File::create or os.Create fails the errors they return already contain the information what and why something failed. So what information does "failed to create file: " add?

The error from Rust's File::create basically only contains the errno result. So it's eg. "permission denied" vs "failed to create file: permission denied".

Re: Thoughts on Go vs. Rust vs. Zig

#114
post #87
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…

That seems unusual. I would assume trivial means the default approach works for most cases. Perhaps mutable global variables are not a common use case. Unsafe might make it easier, but it’s not obvious and probably undesired. I don’t know Rust, but I’ve heard pockets of unsafe code in a code base can make it hard to trust in Rust’s guarantees. The compromise feels like the language didn’t actually solve anything.

Outside of single-initialization/lazy-initialization (which are provided via safe and trivial standard library APIs: https://doc.rust-lang.org/std/sync/struct.LazyLock.html ) almost no Rust code uses global mutable variables. It's exceedingly rare to see any sort of global mutable state, and it's one of the lovely things about reading Rust code in the wild when you've spent too much of your life staring at C code whose programmers seemed to have a phobia of function arguments.

Re: Thoughts on Go vs. Rust vs. Zig

#115
post #87
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…

That seems unusual. I would assume trivial means the default approach works for most cases. Perhaps mutable global variables are not a common use case. Unsafe might make it easier, but it’s not obvious and probably undesired. I don’t know Rust, but I’ve heard pockets of unsafe code in a code base can make it hard to trust in Rust’s guarantees. The compromise feels like the language didn’t actually solve anything.

[deleted]

Re: Thoughts on Go vs. Rust vs. Zig

#116
post #87
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…

That seems unusual. I would assume trivial means the default approach works for most cases. Perhaps mutable global variables are not a common use case. Unsafe might make it easier, but it’s not obvious and probably undesired. I don’t know Rust, but I’ve heard pockets of unsafe code in a code base can make it hard to trust in Rust’s guarantees. The compromise feels like the language didn’t actually solve anything.

> I would assume trivial means the default approach works for most cases. Perhaps mutable global variables are not a common use case. Unsafe might make it easier, but it’s not obvious and probably undesired.

I'm a Rust fan, and I would generally agree with this. It isn't difficult, but trivial isn't quite right either. And no, global vars aren't terribly common in Rust, and when used, are typically done via LazyLock to prevent data races on intialization.

> I don’t know Rust, but I’ve heard pockets of unsafe code in a code base can make it hard to trust in Rust’s guarantees. The compromise feels like the language didn’t actually solve anything.

Not true at all. First, if you aren't writing device drivers/kernels or something very low level there is a high probability your program will have zero unsafe usages in it. Even if you do, you now have an effective comment that tells you where to look if you ever get suspicious behavior. The typical Rust paradigm is to let low level crates (libraries) do the unsafe stuff for you, test it thoroughly (Miri, fuzzing, etc.), and then the community builds on these crates with their safe programs. In contrast, C/C++ programs have every statement in an "unsafe block". In Rust, you know where UB can or cannot happen.

Re: Thoughts on Go vs. Rust vs. Zig

#117

> Other features common in modern languages, like tagged unions or syntactic sugar for error-handling, have not been added to Go. > It seems the Go development team has a high bar for adding features to the language. The end result is a language that forces you to write a lot of boilerplate code to implement logic that could be more succinctly expressed in another language. Being able to implement logic more succinct…

Python's f = open('foo.txt', 'w') is even more succinct, and the exception thrown on failure will not only contain the reason, but the filename and the whole backtrace to the line where the error occurred.

We were taught not to use exceptions for control flow, and reading a file which does not exist is a pretty normal thing to handle in code flow, rather than exceptions.

That simple example in Python is missing all the other stuff you have to put around it. Go would have another error check, but I get to decide, at that point in the execution, how I want to handle it in this context

Re: Thoughts on Go vs. Rust vs. Zig

#118
post #93

The reason I really like Zig is because there's finally a language that makes it easy to gracefully handle memory exhaustion at the application level. No more praying that your program isn't unceremoniously killed just for asking for more memory - all allocations are assumed fallible and failures must be handled explicitly. Stack space is not treated like magic - the compiler can reason about its maximum size by exam…

> No more praying that your program isn't unceremoniously killed just for asking for more memory - all allocations are assumed fallible and failures must be handled explicitly. But for operating systems with overcommit, including Linux, you won't ever see the act of allocation fail, which is the whole point. All the language-level ceremony in the world won't save you.

I imagine people who care about this sort of thing are happy to disable overcommit, and/or run Zig on embedded or specialized systems where it doesn't exist.

Re: Thoughts on Go vs. Rust vs. Zig

#119
post #2

> Many people seem confused about why Zig should exist if Rust does already. It’s not just that Zig is trying to be simpler. I think this difference is the more important one. Zig wants you to excise even more object-oriented thinking from your code. I feel like Zig is for the C / C++ developers that really dislike Rust. There have been other efforts like Carbon, but this is the first that really modernizes the langu…

Rust is hard in that it gives you a ton of rope to hang yourself with, and some people are just hell bent on hanging themselves. I find Rust quite easy most of the time. I enjoy the hell out of it and generally write Rust not too different than i'd have written my Go programs (i use less channels in Rust though) . But i do think my comment about rope is true. Some people just can't seem to help themselves.

I feel like it is the opposite, Go gives you a ton of rope to hang yourself with and hopefully you will notice that you did: error handing is essentially optional, there are no sum types and no exhaustiveness checks, the stdlib does things like assume filepaths are valid strings, if you forget to assign something it just becomes zero regardless of whether it’s semantically reasonable for your program to do that, no nullability checking enforcement for pointers, etc.

Rust OTOH is obsessively precise about enforcing these sort of things.

Of course Rust has a lot of features and compiles slower.

Re: Thoughts on Go vs. Rust vs. Zig

#120
post #4

For a lot of stuff what I really want is golang but with better generics and result/error/enum handling like rust.

Me too. There’s a huge market for a natively compiled language with GC that has a better type system than Go.

The options I’ve seen so far are: OCaml, D, Swift, Nim, Crystal, but none of them have seen to be able to capture a significant market.

Post reply on HN