Live data from Hacker News

Thoughts on Go vs. Rust vs. Zig

sinclairtarget.com

521–530 of 599 posts

Re: Thoughts on Go vs. Rust vs. Zig

#521
post #398

Earlier quoted context omitted.

One of my favorite talks of all-time is the GDC talk on Overwatch's killcam system. This is the thing that when you die in a multiplayer shooter you get to see the last ~4 seconds of gameplay from the perspective of your killer. https://www.youtube.com/watch?v=A5KW5d15J7I The way Blizzard implemented this is super super clever. They created an entirely duplicate "replay world". When you die the server very quickly "b…

Could you describe what you would consider a good logging solution?

Haven’t found it yet! Jai’s implicit context pointer is interesting. Need to work with it more. It still has lots of limitation. But interesting angle.

Re: Thoughts on Go vs. Rust vs. Zig

#522
post #516

Earlier quoted context omitted.

Rust is a 99% solution to a 1% problem.

Presumably this is gray because it's a quip, but I think that's about right. So, so, so much rust is being written for applications that just don't need it. For almost everything[1] a managed runtime like Go or Java or .NET is going to be just as effectively deployed, significantly cheaper to develop and much cheaper to maintain. And the situations where you really need a "systems programming" environment have been r…

> For almost everything a managed runtime like Go or Java or .NET is going to be just as effectively deployed, significantly cheaper to develop

That might be true. I personally still prefer to use a language with sum-types and exhaustive pattern matching for encoding business logic.

> and much cheaper to maintain.

[citation needed]

> Where are the rustacean routing engines and database backends and codecs and kernels? Not in deployment anywhere, not yet.

It is used at Amazon on Firecracker, S3, EC2, CloudFront, Route 53, and that's just what was publicly talked about in 2020[0].

It is used in Android, including in the Kernel[1].

It is used at Microsoft, including in the Kernel[2].

It is used extensively in Firefox, and less extensively in Chrome. JPEG XL might be reincorporated into them because there's a Rust codec in the works.

For databases, the earliest I remember is TiKV[3], which hit 1.0 back in 2018. There are others since.

> C still rules that world, even for new features.

Sure. So?

[0]: https://aws.amazon.com/blogs/opensource/why-aws-loves-rust-a...

[1]: https://security.googleblog.com/2025/11/rust-in-android-move...

[2]: https://www.thurrott.com/windows/282471/microsoft-is-rewriti...

[3]: https://github.com/tikv/tikv

Re: Thoughts on Go vs. Rust vs. Zig

#523

Earlier quoted context omitted.

There are far more people running/writing Zig on/for systems with overcommit than not. Most of the hype around Zig come from people not in the embedded world.

If we can produce a substantial volume of software that can cope with allocation failures then the idea of using something than overcommit as the default becomes feasible. It's not a stretch to imagine that a different namespace might want different semantics e.g. to allow a container to opt out of overcommit. It is hard to justify the effort required to enable this unless it'll be useful for more than a tiny handful…

> If we can produce a substantial volume of software that can cope with allocation failures then the idea of using something than overcommit as the default becomes feasible.

What would "cope" mean? Something like returning an error message like "can't load this image right now"? Such errors are arguably better than crashing the program entirely but still worth avoiding.

I think overcommit exists largely of fork(). In theory a single fork() call doubles the program's memory requirement (and the parent calling it n times in a row (n+1)s the memory requirement). In practice, the OS uses copy-on-write to avoid both this requirement and the expense of copying. Most likely the child won't really touch much of its memory before exit or exec(). Overallocation allows taking advantage of this observation to avoid introducing routine allocation failures after large programs fork().

So if you want to get rid of overallocation, I'd say far more pressing than introducing alloc failure handling paths is ensuring nothing large calls fork(). Fortunately fork() isn't really necessary anymore IMHO. The fork pool concurrency model is largely dead in favor of threading. For spawning child processes with other executables, there's posix_spawn (implemented by glibc with vfork()). So this is achievable.

I imagine there are other programs around that take advantage of overcommit by making huge writable anonymous memory mappings they use sparsely, but I can't name any in particular off the top of my head. Likely they could be changed to use another approach if there were a strong reason for it.

Re: Thoughts on Go vs. Rust vs. Zig

#524

Earlier quoted context omitted.

Not sure what you mean by "primitive support". Java 22 added FFM (Foreign Function & Memory). It works w/ both on-heap & off-heap memory. It has an Arena interface. https://openjdk.org/jeps/454 https://docs.oracle.com/en/java/javase/25/docs/api/java.base...

So, one year ago? After more than 25 years without it? And a lot of people writing Java can't update to that.

Yeah, FFM adds many quality-of-life features - scoped lifetimes being a standout.

If you just want an arena interface, ByteBuffer has been there since Java 1.4 (2002). It also does off-heap w/ ByteBuffer.allocateDirect().

https://docs.oracle.com/en/java/javase/25/docs/api/java.base...

Re: Thoughts on Go vs. Rust vs. Zig

#525
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…

> There's also no way to shrink the memory underlying a slice. Sorry, that is incorrect: https://pkg.go.dev/slices#Clip > It's a common newbie mistake to think they do work like that, and write "append(s, ...)" instead of "s = append(s, ...)". It might even randomly work a lot of the time. "append(s, ...)" without the assignment doesn't even compile. So your entire post seems like a strawman? https://go.dev/play/p/ic…

Yes, my example was garbled. Thanks @masklinn for correcting it for me below!

Re: Thoughts on Go vs. Rust vs. Zig

#526
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…

> 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…

Another example is the (very recently fixed) documented but unobvious and unenforceable requirements for calling Timer.Reset() [0].

[0] https://pkg.go.dev/time@go1.22.12#Timer.Reset

Re: Thoughts on Go vs. Rust vs. Zig

#527
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.

One other thing I think it misses, is how easy it is to navigate a massive code base because everything looks the same. In a large team, this is crucial and I value the legibility over cleverness (I really dislike meta programming).

Really the only thing I found difficult is finding the concrete implementation of an interface when the interface is defined close to where it is, and when interfaces are duplicated everywhere.

Re: Thoughts on Go vs. Rust vs. Zig

#528

> I’m not the first person to pick on this particular Github comment, but it perfectly illustrates the conceptual density of Rust: But you only need about 5% of the concepts in that comment to be productive in Rust. I don't think I've ever needed to know about #[fundamental] in about 12 years or so of Rust… > In both Go and Rust, allocating an object on the heap is as easy as returning a pointer to a struct from a fu…

> But you only need about 5% of the concepts in that comment to be productive in Rust. The similar argument against C++ is applicable here: another programmer may be using 10% (or a different 5%) of the concepts. You will have to learn that fraction when working with him/her. This may also happen when you read the source code of some random projects. C programmers seldom have this problem. Complexity matters.

A similar problem applies to Go, just inverted. Take iteration. The vast majority of use cases for iterating over containers are map, filter, reduce. Go doesn't have these functions. That's very simple! All Go developers are aligned here: just use a for loop. There's no room for "10% of concepts corners", there's just that 1 corner.

But, for loops get tedious. So people will make helper functions. Generic ones today, non-generic in the past. The result is that you have a zoo of iteration-related helper functions all throughout. You'll need to learn those when onboarding to a new code base as well. Go's readability makes this easier, but by definitions everything's entirely non-standard.

Re: Thoughts on Go vs. Rust vs. Zig

#529

Earlier quoted context omitted.

You phrase that as if 0-5% of a program being harder to write disqualifies all the benefits of isolating memory safety bugs to that 0-5%. It doesn't.

And it can easily be more than 5%, since some projects both have lots of large unsafe blocks, and also the presence of an unsafe block can require validation of much more than the block itself. It is terrible of you and overall if my understanding is far better than yours. And even your argument taken at face value is poor, since if it is much harder, and it is some of the most critical code and already-hard code, li…

Even embedded kernels can and regularly do have < 5% unsafe code.

Re: Thoughts on Go vs. Rust vs. Zig

#530
post #379

> I’m not the first person to pick on this particular Github comment, but it perfectly illustrates the conceptual density of Rust: But you only need about 5% of the concepts in that comment to be productive in Rust. I don't think I've ever needed to know about #[fundamental] in about 12 years or so of Rust… > In both Go and Rust, allocating an object on the heap is as easy as returning a pointer to a struct from a fu…

> Rust can also do arena allocations, and there is an allocator concept in Rust, too. Just a pure question: Is Rust allocator global? (Will all heap allocations use the same allocator?)

Rust, as a language, has no allocator.

The standard library provides a global allocator. The collections in the standard library currently use that allocator.

It also provides an unstable interface for allocators in general. That's of course useful someday, but also doesn't prevent people from using whatever allocators they want in the meantime. It just means that libraries that want to be generic over one cannot currently agree. The standard library collections also will use that once it becomes stable.

Post reply on HN