4 ms·
The reason I like this is because of one of the principles that Go espouses pretty heavily - never break backwards compatibility. If I install v1 of your packag
by sudhirj 5y ago
The reason I like this is because of one of the principles that Go espouses pretty heavily - never break backwards compatibility. If I install v1 of your package, I want it never to break. You can always improve performance, add more methods, etc, but the normal Go upgrade does not involve any code changes at all. The tools formalise that for modules as well, and encourage building a new module altogether if backwards compatibility is being broken.
If it’s not being broken, it’s not a major version update, and major breaking updates are better off as new separate modules.
- grey-area 5y agoExcept in practice in all real software (including the go language!) minor and patch versions break importers all the time in small ways, AND major versions are usually used to indicate significant new features, not just breaking changes. So your claim is reduced to ‘I don’t want v1 to break my software in ways that the dependency finds important enough for a major version’. Not quite as reassuring is it? Plenty of security fixes and undefined behaviour fixes break importers all the time, and often importers and exporters disagree about the severity of that. Sticking with v1 will not save you that pain. I preferred the situation before where there was strong social pressure never to break the main branch.
- hsn915 5y agoThis is a cultural issue. It's not inevitable that by developing a module over time that you constantly break compability AND you want all people that depend on you to upgrade version. Go encourages the opposite approach. If your API is not stable, don't publish a package for public consumption, or, make sure to clearly mark it as unstable, so people know what to expect. One of the absolute best features of Go is stability. If I have a project written a few years ago, I can always run it against the latest Go compiler and know that it will still work. Why does this matter? I'll give you a counter example. In 2016 I wanted to work on a mobile application project and I just picked React Native because I heard it lets you easily create cross platform applications. I worked on it for a few weeks, then left it for about two or three months. When I tried to pick it up again, I installed the latest versions of node and npm and upgraded all packages. The project stopped working. I had no idea what went wrong. The error messages were obtuse and several layers deep. I tried to debug it for weeks to no avail. As a result, I abandoned the project and built just an Android version using Kotlin and Android Studio.
- grey-area 5y agoIt certainly is a cultural issue which is why it shouldn’t be enforced by tooling! I also completely agree about the value of stability, which is why I don’t like this change which paradoxically encourages more churn (normalises v2,v3 etc for breaking changes, normalises large breaking changes and rewriting apis). All APIs are slightly unstable in some sense (even adding fields can be a breaking change), so the aim should be to minimise version bloat and breaking changes and provide stability for importers, which the go language has done an amazing job at for the last decade. To give you a counter-example the sengrid api in go has had multiple large breaking changes/rewrites and has used this v2/v3 etc scheme. It’s still a horrible experience as an importer and I’d rather they remained stable instead of introducing massive churn with the cop-out that the old unsupported version didn’t change. In dependencies I import I want a perpetual v1 which doesn’t change over a decade and just slowly improves, not v31 - new improved rewrite this year! Which this rule explicitly encourages.
- tialaramex 5y ago> All APIs are slightly unstable in some sense (even adding fields can be a breaking change) Of course adding fields is a breaking change. It has never ceased to astonish me how little most programmers understand compatibility, I remember wrestling with libpng getting them to understand that e.g. no, "tidying up" the order of fields in a public structure you've published isn't safe back in the 1990s before they came to god and actually provided sane APIs which hide internal data structures. Now, it's true that Hyrum's Law means any detectable change, even if it was never documented, will break somebody if there are enough people depending on your system. That's a big deal if you're the Linux kernel, or the HTTP/1.1 protocol, as it means even trivial "this can't break anything" fixes may break stuff. For example, as I understand it Google once broke search in Asia by changing an internal constant so that a hashmap would re-allocate (thus invalidating pointers to items in the map) slightly earlier. C++ code relying on pointers to just magically stay valid across inserts was completely wrong before they broke it, but anybody staring at a 500 page on google.com doesn't care why it broke they just want it fixed. Most of us needn't much worry about Hyrum's law. That would be, as an old boss repeatedly told us, "A good problem to have" because it means you're having enormous impact.
- miki123211 5y agoThe problem here is that we add too much extra meaning to version identifiers. In semantic versioning, if you're at 1.38 and want to release a cool new version with many cool features and a much faster engine, while still retaining backwards compatibility, you're stuck with releasing a 1.39. If you call your new version 2.0, you signify that it's backwards incompatible. We should have two differently-looking version identifiers, one for compatibility-tracking purposes and one for signifying the scope of changes to humans. The compatibility version numbers could look like 2ah4, where the first number is the major version, the letter (or series of letters) is a minor, increasing alphabetically and going to "aa" after "z", and the last number is a patch.
- grey-area 5y agoI think they are always fuzzy and that’s fine, as long as tooling doesn’t make incorrect assumptions about meaning. Different exporters and importers have different stability requirements and expectations - it’s negotiated.