Live data from Hacker News

Lies we tell ourselves to keep using Golang (2022)

fasterthanli.me

361–370 of 526 posts

Re: Lies we tell ourselves to keep using Golang (2022)

#361
post #151

Earlier quoted context omitted.

Uhh, maybe. Where is the tradeoff analysis? Yeah, you might regret using Go when some zero value you forget to fill in somewhere pops up later and ruins your pipeline. But are you considering all the issues that didn't pop up because you chose Go? Java's boilerplate code? Rust and C++'s lifetime analysis and memory management? C's lack of tooling? Python/Typescript's runtime errors? Functional languages' tiny employe…

Go is very boilerplate. It requires at least 3 lines of error checking every 1 line of actual code. Also it doesn't have packed structs so it's completely incapable of doing low level networking or to handle binary files (you can of course do all the bitwise operations yourself… but is it sensible to use a language that is more error prone than C in 2024?). Also due to its lack of A LOT of system calls, you will need…

I’m not sure I understand the packed structs complaint. I have used Go to read binary data and it’s quite easy. You just need to ensure that all of your struct fields have fixed sizes e.g. int32 or [4]int64 or whatever. Unless I’ve misunderstood what you mean?

Re: Lies we tell ourselves to keep using Golang (2022)

#362
post #79

Earlier quoted context omitted.

I think this is exactly the right way to understand Go - it's targetted at building servers in environments where having strong consistency of code and a short ramp up time for junior engineers is valuable - i.e. it's perfect for all the big corp scenarios that Java was used for. I think maybe the more common, but less helpful comparison of go vs rust comes from the fact that they are both part of a new wave of langu…

> consistency of code There are many stylecheck tools that should be apart of a good stack. Accepting the creator's style is putting a lot of weight on their opinion. Most organizations have their own preferences for good reason. > short ramp up for junior engineers Junior engineers aren't a place you're concerned on being productive. Most of the time at that stage in someone's career they should be learning more, ge…

> Both of those things have very little to do with server environments

My experience of bigcorp is that they need lots of servers (http is the modern bailer twine) and want developers to act as far as possible as indistinguishable resource. They will have rotating, high churn, globally distributed teams of vendors, contractors, consultants, internal staff and the teams will encompass a vast range of skill levels and abilities.

Some languages amplify skill level disparity, some attenuate it.

Re: Lies we tell ourselves to keep using Golang (2022)

#363
I feel like the author is fed up with being disagreed with, yet makes very opinionated statements about how others should (or will, at some point in the future) feel. They make good points about problems in Go, but I gotta say they also make a lot of points that might never become a problem at all.

I've written code that runs in production for 20 years now and every language I ever shipped software with, from ASP, PHP, and C# to Swift, TypeScript and Rust, one thing is always true: there's a pretty good reason the language was picked, and yet a long list of grievances. The reason a language is picked is most often productivity, some belief that software will ship more safely and often if we pick this language. Of course that belief can be uninformed and proven wrong later. But it's really hard to say, for any language, that "you will regret picking this language".

Sure maybe you shouldn't pick PHP for your new startup backend because you'll have a harder time finding developers. Maybe you shouldn't pick Python because despite asyncio there's still that one call you accidentally did that will lock up your highly concurrent service. Maybe you shouldn't pick Java because it's got verbose factories and something about billion dollar mistakes. Possibly picking Rust is a mistake because your developer team will spend 80% of their time fighting the borrow checker. Picking Swift to do your backend seems rather odd, and C++ is too risky with all its undefined behaviors and segmentation faults. Beware of Node.js unless you're ready to dedicate beefy RAM instances to it.

That is of course all hyperbole, I've seen productive code in all of the above languages. And I should add that many of them were not designed any more than Go was, to address one of the author's concerns. I've picked Go many times since it hit 1.0 and I don't regret it, even with production code that is over 10 years old. Go does concurrent processes and I/O really well. The GC works very well for long-running programs with lots and lots of individual goroutines. I also saw developers that had never touched Go enter the code base and make productive edits, which I consider a benefit of Go's simple design (or non-design, as per the author). I've also done similar systems in other languages, especially Node.js, Python, and Rust, but they haven't been as productive in my experience for this use case.

Ironically code written in Rust did wake me up in the middle of the night more than Go did, possibly because it was harder to express the mental model the way originally intended, and instead the code was written to satisfy the computer's memory model. I would still use Rust every day for things where that matters more, but the author seemed to imply somehow avoiding Go avoids unexpected errors, but they happen in every language.

TLDR: Programming languages live on because they make people feel productive. Maybe this feeling is aligned with the business needs, maybe not. But don't go saying that everyone should avoid a language entirely because of your personal experiences.

Re: Lies we tell ourselves to keep using Golang (2022)

#364

Not sure why Go is compared to Rust all the time, whilst most appropriate comparison is Java.

Because someone decides what language to write a new thing in is very likely to consider Go and Rust. They are very unlikely to consider Java. Are Rust and Go sufficiently different that they should each be chosen in different cases? Sure! But that’s literally why someone would consider both and pick one.

Not considering Java is just as dumb as not considering Go or Rust.

Re: Lies we tell ourselves to keep using Golang (2022)

#365

Earlier quoted context omitted.

Bah, no, I hated that you had to wrap basically every code block in a try/catch in Java, because the underlying lib could change and suddenly throw a Runtime-Exception. At the same time Checked Exceptions were a nightmare as well, because suddenly they were part of the contract, even though maybe wrong later.

> the underlying lib could change and suddenly throw a Runtime-Exception. And what would you do in that case? Since this is a future change your existing code presumably wouldn't know what else to do but throw its own exception, so why not just let that one propagate?

Always depends on which level it happens

Re: Lies we tell ourselves to keep using Golang (2022)

#366
post #66

Earlier quoted context omitted.

Exception and explicit on-the-spot handling are not the only two ways to handle failing processes. Optional/result types wrapping the are a clean way to let devs handle errors, for instance, and chaining operations on them without handling errors at every step is pretty ergonomic.

Rust's error handling evolution is hilarious. In the beginning, the language designers threw out exceptions --- mostly, I think, because Go was fashionable at the time. Then, slowly, Rust evolved various forms of syntactic sugar that transformed its explicit error returns into something reminiscent of exceptions. Once every return is a Result, every call a ?, and every error a yeet, what's the difference between your…

The big difference is API stability, one of the primary focuses of Rust.

Re: Lies we tell ourselves to keep using Golang (2022)

#367

Earlier quoted context omitted.

> what's the difference between your program and one with exceptions Because errors as values are explicit. You're not forced to use ? everywhere; you can still process errors however you like, or return them directly to the calling function so they deal with it. They're not separate control flow like exceptions, and they're not a mess like Go's.

No, because you end up with a function coloring problem that way. A function that returns something other than Result has to either call only infallible code or panic on error, and since something can go wrong in most code, the whole codebase converges as time goes to infinity on having Result everywhere. Yeah, yeah, you can say it's explicit and you can handle it how you want and so on, but the overall effect is jus…

Function "coloring" is good! It's not a problem here and it's overblown as a problem in general. If something fails recoverably then it should be indicated as such.

Re: Lies we tell ourselves to keep using Golang (2022)

#368
post #339

Earlier quoted context omitted.

I forgot: The tenet "accept interfaces, return structs" is violated all over by returning the `error` interface. IMO it's okay to make behaviour-exceptions specifically for error handling. Rust for example doesn't really have builtin behaviour exceptions specifically for errors, they're generic to sumtypes and just happen to work well for errors. But then in practice you must resort to thiserror or anyhow helper crat…

> The tenet "accept interfaces, return structs" is violated all over by returning the `error` interface. To be fair, that expression came from a blogger who often wrote about Go. It is not a tenet held by the Go project. In fact, Rob Pike has made clear that he considers it to be misguided advice. It is only violated in the same way returning Result in Rust violates the assertion I made up for this comment: Do not re…

https://go.dev/wiki/CodeReviewComments#interfaces

Re: Lies we tell ourselves to keep using Golang (2022)

#369
post #312

Context for those unaware: This article was a response to a 2022 HN thread [1] about the original article of the author's. Then the following discussion happened: [2]. First off, let's appreciate the fact the author has managed to write this humongous article in a day. That's some writing skill. And indeed, leveraging writing skills to unleash a flood of words in order to overwhelm anyone trying to respond is just th…

Yeah I mean if you care about correctness at scale Rust is basically the only imperative language worth using, due to its separation between mutable and immutable state. I believe having that separation is a fundamental requirement for correctness at scale. I would love to see a simpler language than Rust have that kind of separation, but that doesn't exist at the moment.

Not everyone cares about correctness at scale! Python for example is a perfectly fine language to use when getting something out is more important than being correct at scale. A lot of game dev can also live without full correctness because things like player positions can just be fixed up afterwards if there's a bug. But if correctness at scale is a priority, Rust is the only serious imperative option.

Re: Lies we tell ourselves to keep using Golang (2022)

#370

Earlier quoted context omitted.

There are several shortcomings with go's error handling. The author heavily lies onto rust, so the alternative is not exceptions but a `Result ` sum type. No stacktraces and error wrapping forces you to not only invent unique error messages. You must also conceive a unique wrapping message at every call-site so that you can grep the error message and approximate a stacktrace. The weird "return tuple" , which obviousl…

Rust and Go's lack of stack traces are basically equivalent in that you need to call an additional function to add the stack context to the error result. For go you use fmt.Errorf, in Rust you use .context from anyhow (bad practice in many contexts IMO) or .inspect_err + log. It's rather unfortunate that neither has an easy way of capturing a line number + file easily and appending it to the context. Go could easily…

> Go should really have an analogue to Rust's `?`, but you can't really do that in a sane way without sum types

It could be just some simple (hey, that's what go wants to be, right?) macro thing, that just does the everyday `if err!=nil{return ..., err}` for you without having to juggle (and think about) vars.

    b := g(f()?)?
    // var b B
    // {
    //     var a A
    //     var err error
    //     a, err = f()
    //     if err != nil {
    //         return *new(A), *new(B), err
    //     }
    //     var b B
    //     b, err = g(a)
    //     if err != nil {
    //         return *new(A), *new(B), err
    //     }
    //     // no accidental reuse of err
    // }
I mean look how much utterly useless noise this is, and count all the opportunities for mistakes that wouldn't get caught by the compiler.
Post reply on HN