Remix.run Logo
mjw_byrne 5 days ago

The map iteration order change helps to avoid breaking changes in future, by preventing reliance on any specific ordering, but when the change was made it was breaking for anything that was relying on the previous ordering behaviour.

IMO this is a worthwhile tradeoff. I use Go a lot and love the strong backwards compatibility, but I would happily accept a (slightly) higher rate of breaking changes if it meant greater freedom for the Go devs to improve performance, add features etc.

Based on the kind of hell users of other ecosystems seem willing to tolerate (cough Python cough), I believe I am not alone in this viewpoint.

wild_egg 5 days ago | parent | next [-]

Data point of one, but I've been using Go since 2012 and would drop it instantly if any of the backwards compatibility guarantees were relaxed.

Having bugs imposed on you from outside your project is a waste of time to deal with and there are dozens of other languages you can pick from if you enjoy that time sink. Most of them give you greater capabilities as the balance.

Go's stability is a core feature and compensates for the lack of other niceties. Adding features isn't a good reason to break things. I can go use something else if I want to make that trade.

otterley 5 days ago | parent [-]

Respectfully, I don’t think you would just pack up and leave. The cost of switching to an entirely different language—which might have even worse backwards compatibility issues—is significantly higher than fixing bugs you inadvertently introduced due to prior invalid assumptions.

I’d call your bluff.

wild_egg 4 days ago | parent | next [-]

That's a bit bold when you know nothing about me, but sure.

I exist in a polyglot environment and we use Go for things that we expect to sit and do their job for years without modification.

Nothing more annoying with these than needing to update a runtime to patch a CVE and suddenly needing to invest two weeks to handle all the breaking changes. Go lets us take 5 minutes to bump the version number in the Dockerfile and CI configs and move on to more important work.

I'm not suggesting we'd go rewrite all of those if Go relaxed its guarantees but we'd stop picking it to write new things in and it would slowly disappear as we decommission the existing services over the years.

otterley 3 days ago | parent [-]

Every language and its environment has issues. Switching always introduces a new set of problems, some of which could be worse, and many of which you won't have anticipated when you encounter them.

hn34381 4 days ago | parent | prev [-]

Also, there is a time and a place for things.

Breaking API changes in a minor version update sucks and is often an unexpected time sink, and often mandatory because it has some security patch, critical bug fix, or something.

Breaking API changes in a major version update is expected, can be planned for, and often can be delayed if one chooses.

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

The map iteration order was always "random", but imperfectly so prior to Go 1.3. From memory, it picked a random initial bucket, but then always iterated over that bucket in order, so small maps (e.g. only a handful of elements) actually got deterministic iteration order. We fixed that in Go 1.3, but it broke a huge number of tests across Google that had inadvertently depended on that quirk; I spent quite a few weeks fixing tests before we could roll out Go 1.3 inside Google. I imagine there was quite a few broken tests on the outside too, but the benefit was deemed big enough to tolerate that.

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

I'd consider stuff like that part of the opinion the language has. Go's opinion is that backwards compatibility at all reasonable cost is a priority.

When it comes to ecosystems, the opinions have trade-offs. I would say that Go's approach to dependencies, modules and workspaces is one of those. As a language it mostly stays out of your way, but correcting imports because it pulled in the wrong version, or dealing with go.mod, go.work and replace directives in a monorepo, gets old pretty fast (to the extent it's easier to just have a monorepo-wide go.mod with literally every dependency in it). At least it's an improvement over having to use a fairly specific directory structure though.

jerf 5 days ago | parent | prev | next [-]

Breaking iteration order was also well established as a valid move. Several other languages had already made a similar change, much later in their own lifecycle than Go did. That helps a lot, because it shows it is largely just an annoyance, mostly affecting tests.

hinkley 4 days ago | parent | prev [-]

Java 5 was a fun upgrade for a lot of people because it caused JUnit tests to run in a different order. Due to hashtable changes altering the iteration of the reflected function names.

Don’t couple your tests, kids!