Most active commenters

    ←back to thread

    Go is still not good

    (blog.habets.se)
    644 points ustad | 16 comments | | HN request time: 0.626s | source | bottom
    Show context
    blixt ◴[] No.44983245[source]
    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.

    replies(18): >>44983384 #>>44983427 #>>44983465 #>>44983479 #>>44983531 #>>44983616 #>>44983802 #>>44983872 #>>44984433 #>>44985251 #>>44985721 #>>44985839 #>>44986166 #>>44987302 #>>44987396 #>>45002271 #>>45002492 #>>45018751 #
    traceroute66 ◴[] No.44983465[source]
    > Just all-around a trusty tool in the belt

    I agree.

    The Go std-lib is fantastic.

    Also no dependency-hell with Go, unlike with Python. Just ship an oven-ready binary.

    And what's the alternative ?

    Java ? Licensing sagas requiring the use of divergent forks. Plus Go is easier to work with, perhaps especially for server-side deployments.

    Zig ? Rust ? Complex learning curve. And having to choose e.g. Rust crates re-introduces dependency hell and the potential for supply-chain attacks.

    replies(8): >>44983495 #>>44983537 #>>44983543 #>>44983603 #>>44983770 #>>44985640 #>>44985845 #>>44988378 #
    1. tempay ◴[] No.44983770[source]
    > Rust crates re-introduces dependency hell and the potential for supply-chain attacks.

    I’m only a casual user of both but how are rust crates meaningfully different from go’s dependency management?

    replies(2): >>44983910 #>>44984003 #
    2. tzekid ◴[] No.44983910[source]
    I think it's because go's community sticks close to the standard library:

    e.g. iirc. Rust has multiple ways of handling Strings while Go has (to a big extent) only one (thanks to the GC)

    replies(2): >>44986713 #>>44987698 #
    3. jaas ◴[] No.44984003[source]
    Go has a big, high quality standard library with most of what one might need. Means you have to bring in and manage (and trust) far fewer third party dependencies, and you can work faster because you’re not spending a bunch of time figuring out what the crate of the week is for basic functionality.
    replies(1): >>44984244 #
    4. zozbot234 ◴[] No.44984244[source]
    Rust intentionally chooses to have a small standard library to avoid the "dead batteries" problem. But the Rust community also maintains lists of "blessed" crates to try and cope with the issue of having to trust third-party software components of unknown quality.
    replies(2): >>44984529 #>>44986760 #
    5. traceroute66 ◴[] No.44984529{3}[source]
    > Rust intentionally chooses to have a small standard library to avoid the "dead batteries" problem.

    There is a difference between "small" and Rust's which is for all intents and purposes, non-existent.

    I mean, in 2025, not having crypto in stdlib when every man and his dog is using crypto ? Or http when every man and his dog are calling REST APIs ?

    As the other person who replied to you said. Go just allows you to hit the ground running and get on with it.

    Having to navigate the world of crates, unofficially "blessed" or not is just a bit of a re-inventing the wheel scenario really....

    P.S. The Go stdlib is also well maintained, so I don't really buy the specific "dead batteries" claim either.

    replies(5): >>44985298 #>>44985343 #>>44985737 #>>44986423 #>>44987020 #
    6. deagle50 ◴[] No.44985298{4}[source]
    > I mean, in 2025, not having crypto in stdlib when every man and his dog is using crypto ? Or http when every man and his dog are calling REST APIs ?

    I'm not and I'm glad the core team doesn't have to maintain an http server and can spend time on the low level features I chose Rust for.

    7. tremon ◴[] No.44985343{4}[source]
    I think having http in the standard library is a perfect example of the dead batteries problem: should the stdlib http also support QUIC and/or websockets? If you choose to include it, you've made stdlib include support for very specific use cases. If you choose not to include it, should the quic crate then extend or subsume the stdlib http implementation? If you choose subsume, you've created a dead battery. If you choose extend, you've created a maintenance nightmare by introducing a dependency between stdlib and an external crate.
    8. tuetuopay ◴[] No.44985737{4}[source]
    Sorry but for most programming tasks I prefer having actual data containers with features than an HTTP library: Set, Tree, etc types. Those are fundamental CS building blocks yet are absent from the Go standard library. (well, they were added pretty recently, still nowhere near as featureful than std::collection in Rust).

    Also, as mentioned by another comment, an HTTP or crypto library can become obsolete _fast_. What about HTTP3? What about post-quantum crypto? What about security fixes? The stdlib is tied to the language version, thus to a language release. Having such code independant allows is to evolve much faster, be leaner, and be more composable. So yes, the library is well maintained, but it's tied to the Go version.

    Also, it enables breaking API changes if absolutely needed. I can name two precendents:

    - in rust, time APIs in chrono had to be changed a few times, and the Rust maintainers were thankful it was not part of the stdlib, as it allowed massive changes

    - otoh, in Go, it was found out that net.Ip has an absolutely atrocious design (it's just an alias for []byte). Tailscale wrote a replacement that's now in a subpackage in net, but the old net.Ip is set in stone. (https://tailscale.com/blog/netaddr-new-ip-type-for-go)

    replies(1): >>44989385 #
    9. duped ◴[] No.44986423{4}[source]
    Do you think C and C++ should have http or crypto in their standard libraries?
    replies(1): >>44987527 #
    10. adastra22 ◴[] No.44986713[source]
    What does String/OsSfeing have to do with garbage collection?
    11. jen20 ◴[] No.44986760{3}[source]
    Different trade offs, both are fine.

    The downside of a small stdlib is the proliferation of options, and you suddenly discover(ed?, it's been a minute) that your async package written for Tokio won't work on async-std and so forth.

    This has often been the case in Go too - until `log/slog` existed, lots of people chose a structured logger and made it part of their API, forcing it on everyone else.

    replies(1): >>45001169 #
    12. arlort ◴[] No.44987020{4}[source]
    The go stdlib is well maintained and featureful because Google is very invested in it being both of those things for the use cases

    That works well for go and Google but I'm not sure how easily that'd be to replicate with rust or others

    13. inferiorhuman ◴[] No.44987527{5}[source]
    Well crypt(3) is part of POSIX so…
    14. diarrhea ◴[] No.44987698[source]
    > Rust has multiple ways of handling Strings

    No, none outside of stdlib anyway in the way you're probably thinking of.

    There are specialized constructs which live in third-party crates, such as rope implementations and stack-to-heap growable Strings, but those would have to exist as external modules in Go as well.

    15. Mawr ◴[] No.44989385{5}[source]
    > Set, Tree, etc types. Those are fundamental CS building blocks

    And if you're engaging in CS then Go is probably the last language you should be using. If however, what you're interested in doing is programming, the fundamental data structures there are arrays and hashmaps, which Go has built-in. Everything else is niche.

    > Also, as mentioned by another comment, an HTTP or crypto library can become obsolete _fast_. What about HTTP3? What about post-quantum crypto? What about security fixes? The stdlib is tied to the language version, thus to a language release. Having such code independant allows is to evolve much faster, be leaner, and be more composable. So yes, the library is well maintained, but it's tied to the Go version.

    The entire point is to have a well supported crypto library. Which Go does and it's always kept up to date. Including security fixes.

    As for post-quantum: https://words.filippo.io/mlkem768/

    > - otoh, in Go, it was found out that net.Ip has an absolutely atrocious design (it's just an alias for []byte). Tailscale wrote a replacement that's now in a subpackage in net, but the old net.Ip is set in stone. (https://tailscale.com/blog/netaddr-new-ip-type-for-go)

    Yes, and? This seems to me to be the perfect way to handle things - at all times there is a blessed high-quality library to use. As warts of its design get found out over time, a new version is worked on and released once every ~10 years.

    A total mess of barely-supported libraries that the userbase is split over is just that - a mess.

    16. surajrmal ◴[] No.45001169{4}[source]
    It would be nice if folks linked crates up into ecosystems thst shared maintainers and guidelines. We don't need everyone using the same stuff, but I'd rather prefer to get 10 different dependences rather than 30. In c++ this plays out in libraries like absl, folly, boost and others. Fewer larger dependencies that bring in a mix of functionality.