Live data from Hacker News

Thoughts on Go vs. Rust vs. Zig

sinclairtarget.com

511–520 of 599 posts

Re: Thoughts on Go vs. Rust vs. Zig

#511
post #125

Earlier quoted context omitted.

The only thing I really found weird syntactically when learning it was the single quote for lifetimes because it looks like it’s an unmatched character literal. Other than that it’s a pretty normal curly-braces language, & comes from C++, generic constraints look like plenty of other languages. Of course the borrow checker and when you use lifetimes can be complex to learn, especially if you’re coming from GC-land, j…

Agreed. In practice Rust feels very much like a rationalized C++ in which 30 years of cruft have been shrugged off. The core concepts have been reduced to a minimum and reinforced. The compiler error messages are wildly better. And the tooling is helpful and starts with opinionated defaults. Which all leads to the knock-on effect of the library ecosystem feeling much more modular, interoperable, and useful.

It's really an ML with type classes and a better syntax (and a non-stupid module sublanguage) that also just happens to be more C-like.

Re: Thoughts on Go vs. Rust vs. Zig

#512

Earlier quoted context omitted.

I tried to get an LLM to write a Raku chapter in the same vein - naah. Had to write it myself: Raku Raku stands out as a fast way to working code, with a permissive compiler that allows wide expression. Its an expressive, general-purpose language with a wide set of built-in tools. Features like multi-dispatch, roles, gradual typing, lazy evaluation, and a strong regex and grammar system are part of its core design. T…

I see that my Raku chapter was downvoted a couple of times. Well OK, I am an unashamed shill for such a fantastic and yet despised language. Don’t knock til you try it. Some comments below on “I want a Go, but with more powerful OO” - well Raku adheres to the Smalltalk philosophy… everything is an object, and it has all the OO richness (rope) of C++ with multiple inheritance, role composition, parametric roles, MOP,…

Probably was downvoted because it seem to copy-paste/derive-off an LLM output since, even if you say you wrote it yourself, some distinct LLM grammar/style characteristics appear. (Could just be you picked them as habit after use of such tools.) It doesn't appear to in same vein either. The submitted article's descriptions are, for each language, {philosophy} & {specific design examples}. Yours is mainly on {design}.

That said, agree Raku is cool. A big disadvantage though it has (or had?), more than the sigils-everywhere syntax & small ecosystem, is performance. It's slower than pre-JIT Python. Go also natively-compiles to self-contained binaries, which some people appreciate. (And there're those that prefer Go's simplicity and don't want very high expressiveness other than specific features.)

Re: Thoughts on Go vs. Rust vs. Zig

#513

Earlier quoted context omitted.

I see that my Raku chapter was downvoted a couple of times. Well OK, I am an unashamed shill for such a fantastic and yet despised language. Don’t knock til you try it. Some comments below on “I want a Go, but with more powerful OO” - well Raku adheres to the Smalltalk philosophy… everything is an object, and it has all the OO richness (rope) of C++ with multiple inheritance, role composition, parametric roles, MOP,…

Probably was downvoted because it seem to copy-paste/derive-off an LLM output since, even if you say you wrote it yourself, some distinct LLM grammar/style characteristics appear. (Could just be you picked them as habit after use of such tools.) It doesn't appear to in same vein either. The submitted article's descriptions are, for each language, {philosophy} & {specific design examples}. Yours is mainly on {design}.…

Well - sure - I meant wrote as in "sourced a set of relevant sentences from ChatGPT and then close edited them to convey precisely what I wanted to say" - got me bang to rights there!

Re: Thoughts on Go vs. Rust vs. Zig

#514

Earlier quoted context omitted.

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.

Indeed the usual error is b := append(a, …)

How is that an error if b is properly referenced? It’s perhaps a waste of memory but not wrong

Re: Thoughts on Go vs. Rust vs. Zig

#515
post #505

Earlier quoted context omitted.

With the same difficulties as Java.

But it's improving fast. They even made the new file-based apps target Native AOT by default ( https://learn.microsoft.com/en-us/dotnet/core/whats-new/dotn... ).

I really do wish them luck! C# is a really nice language and I can't wait to see what they do once they introduce sum types. I've been doing Advent of Code in F# and it's been pretty nice.

Re: Thoughts on Go vs. Rust vs. Zig

#516
post #222

Earlier quoted context omitted.

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

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 really at best a wash with Rust. It's mostly replacing boring middleware (c.f. the linked article). Where are the rustacean routing engines and database backends and codecs and kernels? Not in deployment anywhere, not yet. C still rules that world, even for new features.

[1] Well, everything big enough to need a typesafe high performance platform. The real "everything", to first approximation, should be in python.

Re: Thoughts on Go vs. Rust vs. Zig

#517
post #496

Earlier quoted context omitted.

> If your execution environment is simple enough they can be quite useful and effective Saud by many an engineer whose code was running in systems that were in fact not that simple! What is irksome is that globals are actually just kinda straight worse. Like the code that doesn't use a singleton and simply passes a god damn pointer turns out to be the simpler and easier thing to do. > What types of code are you worki…

> All I want in life is a pure C API. It is simple and elegant and delightful and you can wrap it to run in any programming environment in existence. Sure thing boss, here's that header file populated exclusively by preprocessor macros that you asked for.

Super weird reply.

Re: Thoughts on Go vs. Rust vs. Zig

#518

Earlier quoted context omitted.

Indeed the usual error is b := append(a, …)

How is that an error if b is properly referenced? It’s perhaps a waste of memory but not wrong

Because `append` works in-place, Go slices are amortised, and the backing buffer is shared between `a` and `b`, so unless you never ever use a again it likely will have strange effects e.g.

    a := make([]int, 0, 5)
    a = append(a, 0, 0)
    b := append(a, 1)
    a = append(a, 0)
    fmt.Println(b)
prints

    [0 0 0]
because the following happens:

    a := make([]int, 0, 5)
    // a = [() _ _ _ _ _]
    // a has length 0 but the backing buffer has capacity 5, between the parens is the section of the buffer that's currently part of a, between brackets is the total buffer
    a = append(a, 0, 0)
    // a = [(0 0) _ _ _]
    // a now has length 2, with the first two locations of the backing buffer zeroed
    b := append(a, 1)
    // b = [(0 0 1) _ _]
    // b has length 3, because while it's a different slice it shares a backing buffer with a, thus while a does not see the 1 it is part of its backing buffer:
    // a  = [(0 0) 1 _ _]
    a = append(a, 0)
    // append works off of the length, so now it expands `a` and writes at the new location in the backing buffer
    // a = [(0 0 0) _ _]
    // since b still shares a backing buffer...
    // b = [(0 0 0) _ _]

Re: Thoughts on Go vs. Rust vs. Zig

#519

Re UB: > The idea seems to be that you can run your program enough times in the checked release modes to have reasonable confidence that there will be no illegal behavior in the unchecked build of your program. That seems like a highly pragmatic design to me. This is only pragmatic if you ignore the real world experience of sanitizers which attempt to do the same thing and failing to prevent memory safety and UB issu…

Can you provide the source of "(eg Android definitely has sanitizers running on every commit and yet it wasn’t until they switched to Rust that exploits started disappearing)"?

Here’s the report showing the impact has had on memory vulnerabilities in Rust. I guess you’ll have to take my word that they run sanitizers, I don’t know of any good link summarizing their usage, other than it’s listed in AOSP and has instructions on how to use it.

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

https://source.android.com/docs/security/test/sanitizers

Re: Thoughts on Go vs. Rust vs. Zig

#520
post #480

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…

If we're getting philosophical, we can identify a hierarchy of globals: 1. Read-only (`const`s in Rust). These are fine, no objections. 2. Automatic-lazily-initialized write-once, read-only thereafter (`LazyLock` in Rust). These are also basically fine. 3. Manually-initialized write-once, read-only thereafter (`OnceLock` in Rust). These are also basically fine, but slightly more annoying because you need to be sure t…

Good list.

2 and 3 are basically fine. Just so long as you don’t rely on initialization order. And don’t have meaningful cleanup. C++ initialization fiasco is great pain. Crash on shutdown bugs are soooo common with globals.

4 of have to think about.

And yes 5 is the evilness.

Post reply on HN