Remix.run Logo
traceroute66 4 days ago

> 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.

gf000 4 days ago | parent | next [-]

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

Yeah, these are sagas only, because there is basically one, single, completely free implementation anyone uses on the server-side and it's OpenJDK, which was made 100% open-source and the reference implementation by Oracle. Basically all of Corretto, AdoptOpenJDK, etc are just builds of the exact same repository.

People bringing this whole license topic up can't be taken seriously, it's like saying that Linux is proprietary because you can pay for support at Red Hat..

traceroute66 4 days ago | parent | next [-]

> People bringing this whole license topic up can't be taken seriously

So you mean all those universities and other places that have been forced to spend $$$ on licenses under the new regime also can't be taken seriously ? Are you saying none of them took advice and had nobody on staff to tell them OpenJDK exists ?

Regarding your Linux comment, some of us are old enough to remember the SCO saga.

Sadly Oracle have deeper pockets to pay more lawyers than SCO ever did ....

piva00 4 days ago | parent | next [-]

> So you mean all those universities and other places that have been forced to spend $$$ on licenses under the new regime also can't be taken seriously ? Are you saying none of them took advice and had nobody on staff to tell them OpenJDK exists ?

This info is actually quite surprising to me, never heard of it since everywhere I know switched to OpenJDK-based alternatives from the get-go. There was no reason to keep on the Oracle one after the licencing shenanigans they tried to play.

Why do these places kept the Oracle JDK and ended up paying for it? OpenJDK was a drop-in replacement, nothing of value is lost by switching...

traceroute66 4 days ago | parent [-]

TL;DR: Its impossible to know if anyone on campus has downloaded Oracle Java....Oracle monitors downloads and sends in the auditors...

See link/quote in my earlier reply above.

wing-_-nuts 4 days ago | parent [-]

The licensing thing is such FUD man. Oracle being a terrible company is in no way a decent argument that Java should not be used.

lolc 3 days ago | parent | next [-]

> Oracle being a terrible company is in no way a decent argument that Java should not be used.

Weird, to me that is a strong argument. Choose your stewards.

3 days ago | parent | prev [-]
[deleted]
gf000 4 days ago | parent | prev [-]

I have made a bunch of claims, that are objectively true. From there, basic logical inference says that you can completely freely use Java. Anything else is irrelevant.

I don't know what/which university you talk about, but I'm sure they were also "forced to pay $$$" for their water bills and whatnot. If they decided to go with paid support, then.. you have to pay for it. In exchange you can a) point your finger at a third-party if something goes wrong (which governments love doing/often legally necessary) b) get actual live support on Christmas Eve if needed.

traceroute66 4 days ago | parent [-]

TL;DR: Its impossible to know if anyone on campus has downloaded Oracle Java....

Quote from this article:[1]

     *He told The Register that Oracle is "putting specific Java sales teams in country, and then identifying those companies that appear to be downloading and... then going in and requesting to [do] audits. That recipe appears to be playing out truly globally at this point."*

[1] https://www.theregister.com/2025/06/13/jisc_java_oracle/
gf000 4 days ago | parent | next [-]

That's also true of torrented PhotoShop, Microsoft Office, etc..

Also, as another topic, Oracle is doing audits specifically because their software doesn't phone home to check licenses and stuff like that - which is a crucial requirement for their intended target demographics, big government organizations, safety critical systems, etc. A whole country's healthcare system, or a nuclear power base can't just stop because someone forgot to pay the bill.

So instead Oracle just visits companies that have a license with them, and checks what is being used to determine if it's in accord with the existing contract. And yeah, from this respect I also heard of a couple of stories where a company was not using the software as the letter of the contract, e.g. accidentally enabling this or that, and at the audit the Oracle salesman said that they will ignore the mistake if they subscribe to this larger package, which most manager will gladly accept as they can avoid the blame, which is questionable business practice, but still doesn't have anything to do with OpenJDK..

josefx 4 days ago | parent | prev [-]

> Quote from this article:[1]

The article tries very hard to draw a connection between the licensing costs for the universities and Oracle auditing random java downloads, but nobody actually says that this is what happened.

The waiver of historic fees goes back to the last licensing change where Oracle changed how licensing fees would be calculated. So it seems reasonable that Oracle went after them because they were paying customers that failed to pay the inflated fees.

pjmlp 4 days ago | parent | prev [-]

There are other JVMs that do not descend from OpenJDK, but in general your point stands.

gf000 4 days ago | parent [-]

Yeah I know, but people have trouble understanding the absolutely trivial licensing around OpenJDK, let's not bring up alternative implementations (which actually makes the whole platform an even better target from a longevity perspective! There isn't many languages that have a standard with multiple, completely independent impls).

brabel 3 days ago | parent | prev | next [-]

You forgot D. In a world where D exists, it's hard to understand why Go needed to be created. Every critique in this post is not an issue in D. If the effort Google put into Go had gone on making D better, I think D today would be the best language you could use. But as it is, D has had very little investment (by that I mean actual developer time spent on making it better, cleaning it up, writing tools) and it shows.

maleldil 3 days ago | parent [-]

I don't think the languages are comparable. Go tries to stay simple (whatever that means), while D is a kitchen-sink language.

tempay 4 days ago | parent | prev | next [-]

> 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?

jaas 4 days ago | parent | next [-]

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.

zozbot234 4 days ago | parent [-]

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.

jen20 3 days ago | parent | next [-]

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.

surajrmal 2 days ago | parent [-]

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.

traceroute66 4 days ago | parent | prev [-]

> 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.

tremon 4 days ago | parent | next [-]

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.

deagle50 4 days ago | parent | prev | next [-]

> 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.

tuetuopay 3 days ago | parent | prev | next [-]

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)

Mawr 3 days ago | parent [-]

> 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.

arlort 3 days ago | parent | prev | next [-]

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

duped 3 days ago | parent | prev [-]

Do you think C and C++ should have http or crypto in their standard libraries?

inferiorhuman 3 days ago | parent [-]

Well crypt(3) is part of POSIX so…

tzekid 4 days ago | parent | prev [-]

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)

diarrhea 3 days ago | parent | next [-]

> 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.

adastra22 3 days ago | parent | prev [-]

What does String/OsSfeing have to do with garbage collection?

theshrike79 4 days ago | parent | prev | next [-]

uv + the new way of adding the required packages in the comments is pretty good.

you can go `uv run script.py` and it'll automatically fetch the libraries and run the script in a virtual environment.

Still no match for Go though, shipping a single cross-compiled binary is a joy. And with a bit of trickery you can even bundle in your whole static website in it :) Works great when you're building business logic with a simple UI on top.

richid 4 days ago | parent | next [-]

I've been out of the Python game for a while but I'm not surprised there is yet another tool on the market to handle this.

You really come to appreciate when these batteries are included with the language itself. That Go binary will _always_ run but that Python project won't build in a few years.

pjmlp 4 days ago | parent [-]

Unless it made use of CGO and has dynamic dependencies, always is a bit too much.

mdaniel 3 days ago | parent [-]

Or the import path was someone's blog domain that included a <meta> reference to the actual github repo (along with the tag, IIRC) where the source code really lives. Insanity

pjmlp 3 days ago | parent [-]

I never understood the mentality to have SCM urls as package imports directly on the source code.

mdaniel 3 days ago | parent [-]

Well, that's the problem I was highlighting - golang somehow decided to have the worst of both worlds: arbitrary domains in import paths and then putting the actual ref of the source code ... elsewhere

  import "gopkg.in/yaml.v3" // does *what* now?

  curl https://gopkg.in/yaml.v3?go-get=1 | grep github
  <meta name="go-source" content="gopkg.in/yaml.v3 _ https://github.com/go-yaml/yaml/tree/v3.0.1{/dir} https://github.com/go-yaml/yaml/blob/v3.0.1{/dir}/{file}#L{line}">
oh, ok :-/

I would presume only a go.mod entry would specify whether it really is v3.0.0 or v3.0.1

Also, for future generations, don't use that package https://github.com/go-yaml/yaml#this-project-is-unmaintained

lenkite 4 days ago | parent | prev | next [-]

uv is the new hotness now. Let us check back in 5 years...

traceroute66 4 days ago | parent | prev [-]

> you can go `uv run script.py` and it'll automatically fetch the libraries and run the script in a virtual environment.

Yeah, but you still have to install `uv` as a pre-requisite.

And you still end up with a virtual environment full of dependency hell.

And then of course we all remember that whole messy era when Python 2 transitioned to Python 3, and then deferred it, and deferred it again....

You make a fair point, of course it is technically possible to make it (slightly) "cleaner". But I'll still take the Go binary thanks. ;-)

rsyring 3 days ago | parent [-]

Installing uv is a requirement and incredibly easy.

No, there is no dependency hell in the venv.

Python 2 to 3: are you really still kicking that horse? It's dead...please move on.

morsecodist 3 days ago | parent | prev | next [-]

This just makes it even more frustrating to me. Everything good about go is more about the tooling and ecosystem but the language itself is not very good. I wish this effort had been put into a better language.

iTokio 3 days ago | parent | next [-]

Go has transparent async io and a very nice M:N threading model that makes writing http servers using epoll very simple and efficient.

The ergonomics for this use case are better than in any language I ever used.

layer8 3 days ago | parent [-]

Implementing HTTP servers isn’t exactly a common use case in software development, though.

iTokio 2 days ago | parent [-]

Sorry I didn’t mean implementing a raw http server like nginx, but just writing a backend.

p2detar 3 days ago | parent | prev [-]

> I wish this effort had been put into a better language.

But it is being put. Read newsletters like "The Go Blog", "Go Weekly". It's been improving constantly. Language-changes require lots of time to be done right, but the language is evolving.

4 days ago | parent | prev | next [-]
[deleted]
Luker88 3 days ago | parent | prev | next [-]

> Rust crates re-introduces [...] potential for supply-chain attacks.

I have absolutely no idea how go would solve this problem, and in fact I don't think it does at all.

> The Go std-lib is fantastic.

I have seen worse, but I would still not call it decent considering this is a fairly new language that could have done a lot more.

I am going to ignore the incredible amount of asinine and downright wrong stuff in many of the most popular libraries (even the basic ones maintained by google) since you are talking only about the stdlib.

On the top of my head I found inconsistent tagging management for structs (json defaults, omitzero vs omitempty), not even errors on tag typos, the reader/writer pattern that forces you to to write custom connectors between the two, bzip2 has a reader and no writer, the context linked list for K/V. Just look at the consistency of the interfaces in the "encoding" pkg and cry, the package `hash` should actually be `checksum`. Why does `strconv.Atoi`/ItoA still exist? Time.Add() vs Time.Sub()...

It chock full of inconsistencies. It forces me to look at the documentation every single time I don't use something for more than a couple of days. No, the autocomplete with the 2-line documentation does not include the potential pitfalls that are explained at the top of the package only.

And please don't get me started on the wrappers I had to write around stuff in the net library to make it a bit more consistent or just less plain wrong. net/url.Parse!!! I said don't make my start on this package! nil vs NoBody! ARGH!

None of this is stuff at the language level (of which there is plenty to say).

None of it is a dealbreaker per se, but it adds attrition and becomes death by a billion cuts.

I don't even trust any parser written in go anymore, I always try to come up with corner cases to check how it reacts, and I am often surprised by most of them.

Sure, there are worse languages and libraries. Still not something I would pick up in 2025 for a new project.

porridgeraisin 4 days ago | parent | prev [-]

> std-lib

Yes, My favourite is the `time` package. It's just so elegant how it's just a number under there, the nominal type system truly shines. And using it is a treat. What do you mean I can do `+= 8*time.Hour` :D

tux3 4 days ago | parent | next [-]

Unfortunately it doesn't have error handling, so when you do += 8 hours and it fails, it won't return a Go error, it won't throw a Go exception, it just silently does the wrong thing (clamp the duration) and hope you don't notice...

It's simplistic and that's nice for small tools or scripts, but at scale it becomes really brittle since none of the edge cases are handled

arethuza 4 days ago | parent [-]

When would that fail - if the resulting time is before the minimum time or after the maximum time?

tux3 4 days ago | parent [-]

I thankfully found out when writing unit tests instead of in production. In Go time.Time has a much higher range than time.Duration, so it's very easy to have an overflow when you take a time difference. But there's also no error returned in general when manipulating time.Duration, you have to remember to check carefully around each operation to know if it risks going out of range.

Internally time.Duration is a single 64bit count, while time.Time is two more complicated 64bit fields plus a location

porridgeraisin 3 days ago | parent [-]

How is it easy to have an overflow? time.Duration is capped to +- 290 years IIRC.

candiddevmike 4 days ago | parent | prev | next [-]

The way Go parses time strings by default is insane though, even the maintainers regret it. It's a textbook example of being too clever.

nkozyra 4 days ago | parent [-]

By choosing default values instead of templatized values?

Other than having to periodically remember what 0-padded milliseconds are or whatever this isn't a huge deal.

mdaniel 3 days ago | parent [-]

I'm not OP, but I also got tripped up the first time I saw time.Parse("2006-01-02 03:04:05") and was like what the actual?!

https://pkg.go.dev/time#Layout

peterashford 2 days ago | parent [-]

Yeah, that's ugly as fuck. I hate it

pansa2 4 days ago | parent | prev [-]

As long as you don’t need to do `hours := 8` and `+= hours * time.Hour`. Incredibly the only way to get that multiplication to work is to cast `hours` to a `time.Duration`.

In Go, `int * Duration = error`, but `Duration * Duration = Duration`!

porridgeraisin 3 days ago | parent [-]

That is consistent though. Constants take type based on context, so 8 * time.Hour has 8 as a time.Duration.

If you have an int variable hours := 8, you have to cast it before multiplying.

This is also true for simple int and float operations.

  f := 2.0
  3 * f
is valid, but x := 3 would need float64(x)*f to be valid. Same is true for addition etc.
throwawaymaths 3 days ago | parent [-]

It's also completely insane if youve ever done any scientific work.

porridgeraisin 2 days ago | parent [-]

Apart from the extra verbosity, what gives?