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…
Lies we tell ourselves to keep using Golang (2022)
361–370 of 526 posts
Re: Lies we tell ourselves to keep using Golang (2022)
#362Earlier 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…
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)
#363I'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)
#364Not 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.
Re: Lies we tell ourselves to keep using Golang (2022)
#365Earlier 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?
Re: Lies we tell ourselves to keep using Golang (2022)
#366Earlier 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…
Re: Lies we tell ourselves to keep using Golang (2022)
#367Earlier 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…
Re: Lies we tell ourselves to keep using Golang (2022)
#368Earlier 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…
Re: Lies we tell ourselves to keep using Golang (2022)
#369Context 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…
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)
#370Earlier 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…
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.