Hacker News

behnamoh
Why Go is not my favourite language blog.habets.se

bccdeea day ago

Oddly this misses the two big things I hate about Go: Squishy types and no immutability.

1. A nullable SQL string is idiomatically expressed as sql.NullString{String: "my string", Valid: true}. If you forget to initialize `Valid`, it silently sets itself to false and your string is null. I feel like the right solution for this is sum types, but Go says you only need interfaces (and then of course it doesn't use them for stuff like this). And Go doesn't have named arguments, so convention for big functions is to pass a big struct with fields for all the arguments. If you omit a field, it gets zero-intialized, which is nice if you want the default to be zero, but otherwise you can't really have a default value, because there's no way to tell if a given zero was explicit or implicit. And there's no way to ensure that every field gets filled in. I get what they're trying to do with zero values, but it makes the whole type system feel a little bit squishy.

2. I want immutability semantics. Good immutability. Go doesn't even have bad immutability. If you're disciplined, whatever, but people aren't, and I've seen a lot of Go turn into big nasty mutable mudballs.

imiric15 hours ago

> otherwise you can't really have a default value, because there's no way to tell if a given zero was explicit or implicit

You can use pointers, or nullable types. These are not ideal, admittedly, but it's not true that "there's no way".

> there's no way to ensure that every field gets filled in

This can also be done with an exhaustive linter. You might think this isn't great either, but then again, always being reminded that you left out some fields is a) annoying, and b) goes against the benefit of default values altogether.

I agree with you on immutability, though.

I also agree with some of the points in the article, and have my own opinions about things I would like Go to do differently. But if we can agree that all programming languages have warts and that language designers must make tradeoffs, I would say that Go manages to make the right tradeoffs to be an excellent choice for some tasks, a good choice for many tasks, and a bad choice for a few tasks. That makes it my favorite language by a wide margin, though that's also a matter of opinion.

N_Lensa day ago

Not to disagree with the author as I feel their passion for language semantics is probably valuable “somewhere”.

However, as an engineer I find Go very easy and usable despite these nits.

tapirla day ago

Go was my favorite language for a long time, and I have written many books and articles about it. However, since the release of Go 1.22 [1], that is no longer the case. Go 1.22 damaged Go's reputation for promoting explicitness and maintaining strong backward compatibility.

[1]: https://go101.org/blog/2024-03-01-for-loop-semantic-changes-...

bccdeea day ago

for-loop variable capture was maybe the #1 worst decision in the language. It was never what you wanted. I appreciate Go's commitment to backwards-compatibility, but in this case breaking it was the right choice.

tapirla day ago

It is only right for for-each loops.

For 3-clause-for loops, if you have read https://go101.org/blog/2024-03-01-for-loop-semantic-changes-... carefully, it is hard to think it is right.

bccdee17 hours ago

All the examples in that article are very exotic.

  for i, p := 0, (*int)(nil); p == nil; fmt.Println(p == &i) {
    p = &i
  }
Be honest, how many times have you actually seen code which depended on the address of a variable declared in a 3-clause for-loop remaining stable across loop iterations? Nobody does this. It's extremely weird and un-idiomaic. Heck, 3-clause for-loops are somewhat uncommon in and of themselves. Conversely, everyone who writes Go has experienced unintuitive capture issues with for-range loops.

Are you actually aware of any breakages this change has caused?

tapirla minute ago

This one is just an example to demo the backward-capability breaking.

> All the examples in that article are very exotic.

Have you carefully read that article? All? You must be kidding. The article shows several cases used in practice.

nacozarinaa day ago

this is a repeating pattern with languages; there's no commitment to design coherency, no governance, just a mad scamper to stuff features into the project until it becomes an absurd caricature of itself.

C++ did it so egregiously & disastrously you'd think language maintainers would have been scared straight. No, like moths to a flame, it is the preferred hill to die on.

This is how C99 keeps winning when it bleeping should not. It's settled science, however imperfect. It's not getting rearranged because someone read a blog post. It has stability in real-world clock-on-the-wall terms like nothing else.

tapirl18 hours ago

The change made in Go 1.22 for 3-clause-for loops is not a new feature. It simply broke backward compatibility and old Go principles. It is much worse than C++'s stuff features.

tommicaa day ago

What is your language of choice now then?

tapirla day ago

zig now.

DoctorOWa day ago

I'm going to be honest, I always felt like the verbosity was the point of Go. Iirc the whole reason it was invented was to let codebases be as readable as they are writable even for less experienced developers. Why are there Error types when exceptions exist? To force you to acknowledge the possibility for errors. You can easily let your frameworks and libraries handle recovering from panics, but err is unavoidable. You have to, at the very least, put the _.

cwillu20 hours ago

Which is great until you have to troubleshoot an error code surfaced by a nasty web of code with no idea where it came from because the simplest way to handle err is to re-return it, optionally (and more or less uselessly) wrapping it in a new err. I'll take a panic with a stack trace over that any day.

bccdee7 hours ago

The trouble with Go is that, because the language is so simple, the obvious way to do a thing always has a bunch of drawbacks. Taking care of gotchas at a language level means complicating the language, but refusing to do so means complicating code written in your language.

There's a balance to be struck here, but Go is stingy, so you don't get things like error traces and automatic destructors and const semantics even when they would make Go a much simpler language to use.

electroglypha day ago

damn this is old. how relevant is this today?

techbrovanguarda day ago

From my reading, almost all of it.

pjmlp16 hours ago

All of it.

leecommamichael14 hours ago

The author should try Odin.

[deleted]15 hours agocollapsed

logicproga day ago

[dead]

hn-front (c) 2024 voximity
source