Live data from Hacker News

An Honest Review of Go (2025)

benraz.dev

71–80 of 184 posts

Re: An Honest Review of Go (2025)

#71
Thanks for all of the comments!

I want to clarify that I think very highly of Go as a language. I think it gets most things right. It's hard to introduce an abstraction into a language while still making sure that it's not abused. Rust's trait and type system, while powerful have been abused to create some absolutely incomprehensible and long types. Go, on the other hand, doesn't suffer from this issue. If I was too harsh against Go, that was certainly a mistake.

I think that the criticisms of my section on error handling are, for the most part, spot on. My impression was that type erasure for errors was the idiomatic solution, which is patently untrue. When writing the blog post, I was unaware of the functions in the `errors` module as well as the syntactic sugar and general acceptance of downcasting errors. While I would still maintain that Rust errors are more convenient to work with, I must admit that there really isn't any good excuse for my ignorance on this.

When it comes to enums, I stand by my statements on them.

I still believe that it is useful to restrict the values a type might have. And no, I am not using the term enum to mean a rust-style "enum" (tagged union). I am talking about classical enums, more or less as they appear in C.

As an aside, I am not terribly surprised that my website doesn't work well on some browsers. I hacked together the website including the HTML and CSS a couple of years ago and some of the hacks I used I ought to be ashamed of.

Re: An Honest Review of Go (2025)

#72

One of the things I wish more people talked about isn't just the language or the syntax, but the ecosystem . Programming isn't just typing, it's dealing with dependencies and trying to wire everything up so you can have tests, benchmarks, code-generation and build scripts all working together well. When I use modern languages like Go or Rust I don't have to deal with all the stuff added to other languages over the pa…

I like Rust. I don't like that for fairly basic things one has to quickly reach for crates. I suppose it allows the best implementation to emerge and not be concerned with a breaking change to the language itself. I also don't like how difficult it is to cross-compile from Linux to macOS. zig cc exists, but quickly runs into a situation where a linker flag is unsupported. The rust-lang/libc also (apparently?) insists…

The crates.io ecosystem for Rust... is like the amazing girlfriend that you go head over heels for, make her your wife, and then you meet the in-laws ... but it's too late now.

Unlimited access to a bunch of third party code is great as you're getting started.

Until it isn't and you're swimming in a fishing net full of code you didn't write and dependencies you do not want. Everything you touch eventually brings all of tokio along with it. And 3 or 4 different versions of random number generators or base64 utilities, etc. etc.

Re: An Honest Review of Go (2025)

#73
post #68
post #55

Earlier quoted context omitted.

> typing this repetitive (for a reason) pattern became not a problem at all Code is read 10x more than it is written. The noise this pattern introduces inhibits reading and rapid comprehension. Things are getting marginally better now that go has errors.Is and errors.As, and also now that go is starting to get some functional iterators. But go is one of the least quickly-understandable of the modern languages current…

> The noise this pattern introduces Here is the thing... it's NOT a 'noise'. Untill you see handling 'error path' as noise, you will be trapped in searching magic bullet language solution to hide it. We've all been there.

Handling errors doesn’t have to be noisy. Handling errors the way golang requires is.

When it takes five times as long to figure out how a function actually works (not only due to error handling, to be fair), the language has a problem.

Re: An Honest Review of Go (2025)

#74
post #45
post #41

Earlier quoted context omitted.

I think Go's concept of error wrapping is probably unusual to newcomers to the language who might be used to, say, pulling in a dependency for error handling (logrus or whatever) when it's all there in the stdlib in what Go has decided to be the idiomatic way to do errors and logging. It's nice when you understand how to do it well and move on from, say, printing errors directly where they happen rather than creating…

I think it's probably confusing until you understand interfaces, which coming from other languages you might not be familiar with (my guess for what happened in this blog post). If you don't know what an interface is then maybe you assume err.Error() is some kind of string, without realizing Error() is just a required function but the err could be whatever type.

My understanding is that using `error` as a return type performs type erasure and that the only information given to the caller is the value of the `e.Error()` function. I now understand that this isn't the case.

Re: An Honest Review of Go (2025)

#75

Another languages that just “gets” concurrent right (imo) is erlang/elixir. I’ve done elixir for the last 3 years off and on. Can someone with experience in both Go and Elixir compare the two? I’m sure I can have GPT whip up a comparison and see the syntax diffeeences, but I’m curious what the real experience “in the trench” is like.

I've used both professionally. I think elixir has some amazing ideas. I love pattern matching. However! Just like all other interpreted languages, in elixir, I have to go to the call sites of the function that I am editing to understand what it is that is actually available and to understand what I can edit. I don't know what has been passed into my function. The lack of types is not fixed by having a type spec and dialyzer. Pattern matching helps. I wish Go had it. But when it comes to a growing organization, more and more of the codebase cannot fit in your head, and I find that teams and organizations are indeed faster in Go.

I recall hearing that Jose was making progress on types. Not sure where that landed.

Re: An Honest Review of Go (2025)

#76
post #3

I commend Go for popularizing the channel-based concurrency, since I do think that that is a very elegant way of structuring stuff (especially compared to mutexes), but I have to admit that I don’t have a lot of fun writing Go. I agree with a lot of the sentiment of this post; the weirdness with “tuples”, the weirdness of the error types, and etc. It’s not a “bad” language, just one that I don’t enjoy using. Historic…

What are they top 3 languages that you have used that can be used as Go alternatives ranked by fun in your opinion (I am guessing Clojure and Rust are two of them)?

Re: An Honest Review of Go (2025)

#77

Error handling in Go is actually very nice. You do not have unhandled errors, not possible unless you really want to not handle the error. Now I even use it similar in Python, amazing how many errors I did not handle at all. But what got me into using Go is that there is no libc dependency, just system calls, static binary, that is just amazing. I can compile Go compiler in like few minutes. Rust I cannot even compil…

> Rust I cannot even compile after 24h Could I ask what hardware this is on? Even when building LLVM from scratch too as part of building the toolchain (which hasn't been the default for a while now, but could see Gentoo doing so), it never took that long on any hardware I own. (Granted, I never tried on the EEE PC I've got on some drawer, and its 2G of RAM would likely kill the whole thing before it got started.)

On a Lenovo T460 (mid-range laptop from 2016), with a fresh clone of https://github.com/rust-lang/rust/ and the default config:

  $ time ./x.py build
  ... snip ...
  Build completed successfully in 0:21:24

  real    21m24.736s
  user    67m48.195s
  sys     1m54.906s
  
Subsequent builds during development are faster (as 1. it doesn't build the same compiler multiple times, you can use the stage 1 build as normal, stage 2 is not strictly necessary and 2. if you modify one of the constituent crates of the compiler, the ones that are lower in the dep tree don't get recompiled). I've used this laptop on and off for rustc development for the last 10 years. Nowadays I spent more time using a cloud desktop that has much faster IO, but still use it during travels sometimes.

From the sound of it, I suspect that your issue might be that you don't have enough RAM and your build is swapping a lot.

Re: An Honest Review of Go (2025)

#78

Earlier quoted context omitted.

When I use Go, I find I can get more real work done with only the standard library than with any other language I've used (including Java, although that was quite a while ago now). It may not have the most stuff, it is more focused - but I'm okay with esoteric stuff not being in there since the tradeoff seems to be that there are high-quality implementations of e.g. an HTTP client and server, crypto functions, a unit…

Python's standard library seems comparable IME

In my experience, people building APIs w/ python are almost always using frameworks, while people building APIs w/ golang are almost always using stdlib

Re: An Honest Review of Go (2025)

#79
Man this post is a rollercoaster. First half of the post I was absolutely starstruck by how amazing go is(I haven't had time to play with it myself yet), and was making mental note after mental note to try it out asap!

Then I got to the second half of the post, with the things he didn't like about go.

No enums? Wtf? Not having sum types is a lesser evil imo, it places you in the mediocre, but mediocre is mostly ok so that's kinda fine. But no enums? We're stuck with magic numbers? Hell naw, we banished that demon in the nineties, I ain't signing up to bring it back!

Re: An Honest Review of Go (2025)

#80
post #40
post #34

Earlier quoted context omitted.

> I don't like the term "enums" because of the overloading between simple integers that indicate something (the older, more traditional meaning) I disagree with this. I'm old as hell, and I learned programming in a context where enums were always ints, but I remember being introduced to int enums as "we're going to use ints to represent the values of our enum," not "enums are when you use ints to represent a set of v…

"Enum" is literally defined as a numbering mechanism. While integers are the most natural type used to store numbers, you could represent those numbers as strings if you really wanted. The key takeaway is that a enum is a value , not a type. The type the link was struggling to speak of seems to be a tagged union. Often tagged union implementations use enums to generate the tag value, which seems to be the source of c…

Disagree. Enums are named for being enumerable which is not the same thing as simply having an equivalent number.

It’s incredibly useful to be able to easily iterate over all possible values of a type at runtime or otherwise handle enum types as if they are their enum value and not just a leaky wrapper around an int.

If you let an enum be any old number or make the user implement that themselves, they also have to implement the enumeration of those numbers and any optimizations that you can unlock by explicitly knowing ahead of time what all possible values of a type are and how to quickly enumerate them.

What’s a better representation: letting an enum with two values be “1245927” or “0” or maybe even a float or a string whatever the programmer wants? Or, should they be 0 and 1 or directly compiled into the program on a way that allows the programmer to only ever need to think about the enum values and not the implementation?

IMO the first approach completely defeats the purpose of an enum. It’s supposed to be a union type, not a static set of values of any type. If I want the enum to be tagged or serializable to a string that should be implemented on top of the actual enumerable type.

They’re not mutually exclusive at all, it’s just that making enums “just tags” forces you to think about their internals even if you don’t need to serialize them and doesn’t give you enumerability, so why would I even use those enums at all when a string does the same thing with less jank?

Post reply on HN