Live data from Hacker News

Thoughts on Go vs. Rust vs. Zig

sinclairtarget.com

101–110 of 599 posts

Re: Thoughts on Go vs. Rust vs. Zig

#101

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

it's the other way around Rust used to not have operator?, and then A LOT of complaints have been "we don't care, just let us pass errors up quickly" "good luck debugging" just as easily happens simply by "if err!=nil return nil,err" boilerplate that's everywhere in Golang - but now it's annoying and takes up viewspace

> "if err!=nil return nil,err" boilerplate that's everywhere in Golang - but now it's annoying and takes up viewspace

This isn't true in my experience. Most Go codebases I've worked in wrap their errors.

If you don't believe me, go and take a look at some open-source Go projects.

Re: Thoughts on Go vs. Rust vs. Zig

#102

Earlier quoted context omitted.

It entirely prevents race conditions due to the borrow checker and safe constructs like Mutexes. Logical race conditions and deadlocks can still happen.

ah i see, thanks. i have no idea what rust code looks like but from the article it sounds like a language where you have a lot of metadata about the intended usage of a variable so the compiler can safety check. thats its trick.

That's a fairly accurate idea of it. Some folks complain about Rust's syntax looking too complex, but I've found that the most significant differences between Rust and C/C++ syntax are all related to that metadata (variable types, return types, lifetimes) and that it's not only useful for the compiler, but helps me to understand what sort of data libraries and functions expect and return without having to read through the entire library or function to figure that out myself. Which obviously makes code reuse easier and faster. And similarly allows me to reason much more easily about my own code.

Re: Thoughts on Go vs. Rust vs. Zig

#103

Anecdotally, as a result of the traits that made it hard to learn for humans, Rust is actually a great language for LLM. Out of all languages I do development in the past few months: Go, Rust, Python, Typescript; Rust is the one that LLM has the least churn/problems in terms of producing correct and functional code given a problem of similar complexity. I think this outside factor will eventually win more usage for R…

Yeah that's an interesting point, it feels like it should be even better than it is now (I might be ignorant of the quality of the best coding agents atm).

Like rust seems particularly well suited for an agent based workflow, in that in theory an agent with a task could keep `cargo check`-ing it's solutions, maybe pulling from docs.rs or source for imported modules, and get to a solution that works with some confidence (assuming the requirements were well defined/possible etc etc).

I've had a mixed bag of an experience trying this with various rust one off projects. It's definitely gotten me some prototype things working, but the evolving development of rust and crates in the ecosystem means there's always some patchwork to get things to actually compile. Anecdotally I've found that once I learned more about the problem/library/project I'll end up scrapping or rewriting a lot of the LLM code. It seems pretty hard to tailor/sandbox the context and workflow of an agent to the extent that's needed.

I think the Bun acquisition by Anthropic could shift things too. Wouldn't be surprised if the majority of code generated/requested by users of LLM's is JS/TS, and Anthropic potentially being able to push for agentic integration with the Bun runtime itself could be a huge boon for Bun, and maybe Zig (which Bun is written in) as a result? Like it'd be one thing for an agent to run cargo check, it'd be another for the agent to monitor garbage collection/memory use while code is running to diagnose potential problems/improvements devs might not even notice until later. I feel like I know a lot of devs who would never touch any of the langs in this article (thinking about memory? too scary!) and would love to continue writing JS code until they die lol

Re: Thoughts on Go vs. Rust vs. Zig

#104
post #49

I could never get into zig purely because of the syntax and I know I am not alone, can someone explain the odd choices that were taken when creating zig? the most odd one probably being 'const expected = [_]u32{ 123, 67, 89, 99 };' and the 2nd most being the word 'try' instead of just ? the 3rd one would be the imports and `try std.fs.File.stdout().writeAll("hello world!\n");` is not really convincing either for a ba…

I will never understand people bashing other languages for their syntax and readability and then saying that they prefer Rust. Async Rust is the ugliest and least readable language I've ever seen and I've done a lot of heavily templated C++

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

Re: Thoughts on Go vs. Rust vs. Zig

#105

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

Re: Thoughts on Go vs. Rust vs. Zig

#106
post #95

Earlier quoted context omitted.

Any sane Go team will be running errcheck, so I think this is a moot point.

I think it’s still worth pointing out that one language includes it as a feature and the other requires additional tooling.

Which can also be said about Rust and anyhow/thiserror. You won't see any decent project that don't use them, the language requires additional tooling for errors as well.

Re: Thoughts on Go vs. Rust vs. Zig

#107

Earlier quoted context omitted.

"Context" here is just a string. Debugging means grepping that string in the codebase, and praying that it's unique. You can only come up with so many unique messages along a stack. You are also not forced to add context. Hell, you can easily leave errors unhandled, without compiler errors nor warnings, which even linters won't pick up, due to the asinine variable syntax rules.

> Debugging means grepping that string in the codebase, and praying that it's unique. This really isn't an issue in practice. The only case where an error wouldn't uniquely identify its call stack is if you were to use the exact same context string within the same function (and also your callees did the same). I've never encountered such a case. > You are also not forced to add context Yes, but in my experience Go de…

The go stdlib notoriously returns errors without wrapping. I think it has been shifting towards more wrapping more often, but still.

    err1 := foo()
    err2 := bar()
    if err1 != nil || err2 != nil {
        return err1  // if only err2 failed, returns nil!
    }
``` func process() error { err := foo() if err != nil { return err }

    if something {
        result, err := bar()  // new err shadows outer err
        if err != nil {
            return err
        }
        use(result)
    }
    
    if somethingElse {
        err := baz()  // another shadow
        log.Println(err)
    }
    
    return err  // returns foo's err (nil), baz's error lost
} ```

Re: Thoughts on Go vs. Rust vs. Zig

#108
post #11

I really hate the anti-RAII sentiments and arguments. I remember the Zig community lead going off about RAII before and making claims like "linux would never do this" ( https://github.com/torvalds/linux/blob/master/include/linux/... ). There are bad cases of RAII APIs for sure, but it's not all bad. Andrew posted himself a while back about feeling bad for go devs who never get to debug by seeing 0xaa memory segments,…

Have you tried Swift? It has the sort of pragmatic-but-safe-by-default approach you’re talking about.

Re: Thoughts on Go vs. Rust vs. Zig

#109

Generally a good writeup, but the article seems a bit confused about undefined behavior. > What is the dreaded UB? I think the best way to understand it is to remember that, for any running program, there are FATES WORSE THAN DEATH. If something goes wrong in your program, immediate termination is great actually! This has nothing to do with UB. UB is what it says on the tin, it's something for which no definition is…

I think it's common to be taught that UB is very bad when you're new, partly to simplify your debugging experience, partly to help you understand and mentally demarcate the boundaries of what the language allows and doesn't allow, and partly because there are many Standards-Purists who genuinely avoid UB. But from my own experience, UB just means "consult your compiler to see what it does here because this question i…

> But from my own experience, UB just means "consult your compiler to see what it does here because this question is beyond our pay grade."

Careful. It's not just "consult your compiler", because the behavior of a given compiler on code containing UB is also allowed to vary based on specific compiler version, and OS, and hardware, and the phase of the moon.

Re: Thoughts on Go vs. Rust vs. Zig

#110

Earlier quoted context omitted.

I think it's common to be taught that UB is very bad when you're new, partly to simplify your debugging experience, partly to help you understand and mentally demarcate the boundaries of what the language allows and doesn't allow, and partly because there are many Standards-Purists who genuinely avoid UB. But from my own experience, UB just means "consult your compiler to see what it does here because this question i…

> But from my own experience, UB just means "consult your compiler to see what it does here because this question is beyond our pay grade." People are taught it’s very bad because otherwise they do exactly this, which is the problem. What does your compiler do here may change from invocation to invocation, due to seemingly unrelated flags, small perturbations in unrelated code, or many other things. This approach enc…

I understand, but you have to see how you would be considered one of the Standards-Purists that I was talking about, right? If Microsoft makes a guarantee in their documentation about some behavior of UB C code, and this guarantee is dated to about 14 years ago, and I see many credible people on the internet confirming that this behavior does happen and still happens, and these comments are scattered throughout those past 14 years, I think it's safe to say I can rely on that behavior, as long as I'm okay with a little vendor lock-in.
Post reply on HN