Comment by guywithahat
6 months ago
Go is such a great language. If your code base doesn't mind garbage collection and doesn't depend on some external library, everyone should really look at go. Great multithreading, memory safe, great error handling, and a familiar syntax for people coming from C++/Java/etc.
> great error handling
Go get this completely wrong! It use a tuple rather than an enum for potential errors. This means you can forget to check errors and just use the invalid (nil?) return value from the function.
On the other hand, rust uses the Either enum to force you to handle the error. Alternatively you can use the ? operator to pass it to the calling function, which is reflected in the enclosing function's type.
Pet peeves nitpick: it's not even a tuple. Go doesn't have tuples. It just has special-cased "multiple return values", which means that it's often impossible to just stuff the return of a function call (error value and all) into any data structure to aggregate them. You just can't do without first defining a struct since tuples don't exist in Go.
Yep Rust approach won. Pretty much every new language is adopting Result style errors and it's been adapted to plenty of existing languages.
It's a product of functional programming, and for me I can't see how you would ever want to handle errors outside of the functional programming railway-oriented style. For me it's just superior.
Umm, actually, it's specifically a coproduct of functional programming. ;-)
https://en.wikipedia.org/wiki/Coproduct
1 reply →
How is Go memory safe? Memory safety does not mean "leaking memory".
It's absolutely possible to compute wrong pointer offsets. It's absolutely possible to dereference nil. It's absolutely possible to bork ownership and have multiple thread trample a struct. It's absolutely possible to reinterpret memory the wrong way.
I do agree that UAF is not possible (in most cases) due to the GC. That array indexing out of bounds is not possible. But it is by no means "memory safe" to the level Rust is.
> It's absolutely possible to bork ownership and have multiple thread trample a struct.
This is specifically the one place where go is not memory safe IMO.
> It's absolutely possible to compute wrong pointer offsets.
In Go? Without the `unsafe` package (at which point you are explicitly opting out)? How? There's no pointer offset in the first place.
> It's absolutely possible to dereference nil.
Yeah, but that's safe defined behavior in go equivalent to "unwrap"ing a None option in rust. It reliably crashes. It's not like C where it's undefined behavior and you might crash of you might just corrupt random memory or have the optimizer make your code do something even stranger.
It's (really the lack of non-nil types) is one of many reasons why go doesn't produce as reliable software as rust, but it's not a memory safety issue.
> It's absolutely possible to reinterpret memory the wrong way.
Again, without the unsafe package? How?
My Go is a bit rusty (pun intended), so I may have misremembered, especially with the pointer offsets. (just googled it, I did remember it, sorry for the confusion).
>> It's absolutely possible to reinterpret memory the wrong way. > Again, without the unsafe package? How?
Again my go is rusty, but I saw quite a bit of shenanigans in go with pointer casting from what's essentially a collection of void*. However perhaps those casts blow up at runtime? I'm too used to rust where it's explicit where it'll blow up.
>> It's absolutely possible to dereference nil. > Yeah, but that's safe defined behavior in go equivalent to "unwrap"ing a None option in rust. It reliably crashes. It's not like C where it's undefined behavior and you might crash of you might just corrupt random memory or have the optimizer make your code do something even stranger.
Agreed. I conflated "safety" and "robustness" here. The existence of nil is a thorn in the language.
Thanks for the corrections!
Using data races: https://www.ralfj.de/blog/2025/07/24/memory-safety.html
1 reply →
Rust doesn't consider leaking memory to be unsafe.
I mentioned it because I often hear people (not in this thread though) that thanks to its GC preventing memory leaks, Go is memory safe. The GC's role in memory safety is preventing dangling pointers though.
> Great multithreading
Until you stumble upon the countless footguns. At least they generally don’t lead to memory unsafety, just garbage data.
Data Race Patterns in Go
https://www.uber.com/blog/data-race-patterns-in-go/
Zig in spirit is essentially Go without GC. If GC is not reasonable for your usecase Zig seems like an awesome choice. Unfortunately it's probably about 5 to 10 years out from being stable enough for most people being able to write serious applications in it though (notable exceptions being Bun and Ghostty, but they have solid effort behind them keeping them up to date with Zig).
More like Modula-2 in C clothing, given the safety guarantees.
If you're focusing on safety guarantees, sure. If you measure by safety checks included by default instead, it actually has more safety checks than Go (in particular, safety checked numeric operations for overflow).
The other big thing that makes it spiritually like Go is that you follow the same pattern of: allocate resource, immediately defer deallocation.
> If your code base doesn't mind garbage collection and doesn't depend on some external library, everyone should really look at go
I mean, at that point pretty much every language would be a decent choice.
>mention Go
>great error handling
why people so confident being so wrong???
Go has some of the worst error handling I've ever seen, even worse than most exception implementations IMO, and the type system is stupid enough that it's still very easy to write bugs. Go is only surface-level memory safe, you can definitely segfault in Go. And I mean real segfault, not nullptr dereference.