zlacker

[return to "Go is still not good"]
1. blixt+ac[view] [source] 2025-08-22 11:35:29
>>ustad+(OP)
I've been using Go more or less in every full-time job I've had since pre-1.0. It's simple for people on the team to pick up the basics, it generally chugs along (I'm rarely worried about updating to latest version of Go), it has most useful things built in, it compiles fast. Concurrency is tricky but if you spend some time with it, it's nice to express data flow in Go. The type system is most of the time very convenient, if sometimes a bit verbose. Just all-around a trusty tool in the belt.

But I can't help but agree with a lot of points in this article. Go was designed by some old-school folks that maybe stuck a bit too hard to their principles, losing sight of the practical conveniences. That said, it's a _feeling_ I have, and maybe Go would be much worse if it had solved all these quirks. To be fair, I see more leniency in fixing quirks in the last few years, like at some point I didn't think we'd ever see generics, or custom iterators, etc.

The points about RAM and portability seem mostly like personal grievances though. If it was better, that would be nice, of course. But the GC in Go is very unlikely to cause issues in most programs even at very large scale, and it's not that hard to debug. And Go runs on most platforms anyone could ever wish to ship their software on.

But yeah the whole error / nil situation still bothers me. I find myself wishing for Result[Ok, Err] and Optional[T] quite often.

◧◩
2. xyzzyz+6f[view] [source] 2025-08-22 11:56:37
>>blixt+ac
Go was designed by some old-school folks that maybe stuck a bit too hard to their principles, losing sight of the practical conveniences.

I'd say that it's entirely the other way around: they stuck to the practical convenience of solving the problem that they had in front of them, quickly, instead of analyzing the problem from the first principles, and solving the problem correctly (or using a solution that was Not Invented Here).

Go's filesystem API is the perfect example. You need to open files? Great, we'll create

  func Open(name string) (*File, error)
function, you can open files now, done. What if the file name is not valid UTF-8, though? Who cares, hasn't happen to me in the first 5 years I used Go.
◧◩◪
3. nasret+Uf[view] [source] 2025-08-22 12:03:29
>>xyzzyz+6f
Note that Go strings can be invalid UTF-8, they dropped panicking on encountering an invalid UTF string before 1.0 I think
◧◩◪◨
4. xyzzyz+jg[view] [source] 2025-08-22 12:06:09
>>nasret+Uf
This also epitomizes the issue. What's the point of having `string` type at all, if it doesn't allow you to make any extra assumptions about the contents beyond `[]byte`? The answer is that they planned to make conversion to `string` error out when it's invalid UTF-8, and then assume that `string`s are valid UTF-8, but then it caused problems elsewhere, so they dropped it for immediate practical convenience.
◧◩◪◨⬒
5. 0x000x+Jl[view] [source] 2025-08-22 12:38:56
>>xyzzyz+jg
Why not use utf8.ValidString in the places it is needed? Why burden one of the most basic data types with highly specific format checks?

It's far better to get some � when working with messy data instead of applications refusing to work and erroring out left and right.

◧◩◪◨⬒⬓
6. const_+v01[view] [source] 2025-08-22 16:16:06
>>0x000x+Jl
IMO utf8 isn't a highly specific format, it's universal for text. Every ascii string you'd write in C or C++ or whatever is already utf8.

So that means that for 99% of scenarios, the difference between char[] and a proper utf8 string is none. They have the same data representation and memory layout.

The problem comes in when people start using string like they use string in PHP. They just use it to store random bytes or other binary data.

This makes no sense with the string type. String is text, but now we don't have text. That's a problem.

We should use byte[] or something for this instead of string. That's an abuse of string. I don't think allowing strings to not be text is too constraining - that's what a string is!

◧◩◪◨⬒⬓⬔
7. adastr+k41[view] [source] 2025-08-22 16:36:51
>>const_+v01
Not all text is UTF-8, and there are real world contexts (e.g. Windows) where this matters a lot.
◧◩◪◨⬒⬓⬔⧯
8. const_+ea1[view] [source] 2025-08-22 17:04:40
>>adastr+k41
Yes, Windows text is broken in its own special way.

We can try to shove it into objects that work on other text but this won't work in edge cases.

Like if I take text on Linux and try to write a Windows file with that text, it's broken. And vice versa.

Go let's you do the broken thing. In Rust or even using libraries in most languages, you cant. You have to specifically convert between them.

That's why I mean when I say "storing random binary data as text". Sure, Windows almost UTF16 abomination is kind of text, but not really. Its its own thing. That requires a different type of string OR converting it to a normal string.

◧◩◪◨⬒⬓⬔⧯▣
9. adastr+Ab1[view] [source] 2025-08-22 17:12:37
>>const_+ea1
Even on Linux, you can't have '/' in a filename, or ':' on macOS. And this is without getting into issues related to the null byte in strings. Having a separate Path object that represents a filename or path + filename makes sense, because on every platform there are idiosyncratic requirements surrounding paths.

It maybe legacy cruft downstream of poorly thought out design decisions at the system/OS level, but we're stuck with it. And a language that doesn't provide the tooling necessary to muddle through this mess safely isn't a serious platform to build on, IMHO.

There is room for languages that explicitly make the tradeoff of being easy to use (e.g. a unified string type) at the cost of not handling many real world edge cases correctly. But these should not be used for serious things like backup systems where edge cases result in lost data. Go is making the tradeoff for language simplicity, while being marketed and positioned as a serious language for writing serious programs, which it is not.

[go to top]