News for hackers. Stuff that matters.
Re:Go Replaces Interface{} with 'Any' by stormbrew on Tuesday December 14, 2021 @08:25PM (#29560810)
I feel like this is perhaps a bit of a gap in semver tbh. Sometimes a purely additive change can be quite major, in the sense that it shifts the thing in such a fundamental way that you are unlikely to try to interoperate between before and after, and are likely to run into trouble if you do.

Basically, if 1.18 code is extremely unlikely to work against a 1.17 compiler, because a new (technically additive) feature is pervasively threaded through new code, I feel like it's hard to describe them as part of the same epoch.

I don't write enough go to know if that's true for generics, but it seems like it could become true fairly quickly from my experience with other languages.

Re:Go Replaces Interface{} with 'Any' by latortuga on Tuesday December 14, 2021 @08:31PM (#29560873)
This seems like it would apply to literally any new feature - new code won't compile on an old compiler. It isn't the purpose of semver though, semver is trying to help you upgrade old code safely.
Re:Go Replaces Interface{} with 'Any' by stormbrew on Tuesday December 14, 2021 @10:42PM (#29561821)
I think the thing, to me, is that semver is very useful where these things are purely mechanical. This (at least usually) applies to libraries. Semver enables things like lockfiles as used by ruby bundler and later cargo and various other things. But not all systems are upgraded in mechanical ways, and not all 'breaks' are purely mechanical.

This is why you can't really use semver (usefully) for everything. What's a "breaking change" in a word processor?

Languages aren't used like word processors, but they also aren't exactly used like libraries either. People get stuck on language versions for different reasons than why they get stuck on library versions.

At any rate I think in practice I think languages that are trying to hew to semver concepts like this just wind up with a 'fake major version'. Since Rust, for eg., might never go to 2.x the 1. in front of 54 is really just academic. That's the "real" major version as far as anyone needs to know.

A lot of the arguments in this thread seem to be kinda tautological. There's no law that says they have to use semver, nor is there a law that says semver can't be imperfect. "Semver is semver because semver says so" is not a compelling argument.

Re:Go Replaces Interface{} with 'Any' by msbarnett on Tuesday December 14, 2021 @09:31PM (#29561354)
SemVer is about breaking changes to existing code when you upgrade compilers, not about making future code backwards compatible to older compilers.

Every additive language change would be a breaking change in this ReverseSemVer you’re imagining.

Re:Go Replaces Interface{} with 'Any' by eru on Tuesday December 14, 2021 @10:22PM (#29561692)
Only subtractive changes and eg performance changes would not break things in the grandfather comment's scheme.
Re:Go Replaces Interface{} with 'Any' by stormbrew on Wednesday December 15, 2021 @04:06AM (#29563599)
I did not in any way shape or form "propose a scheme." I pointed out what I perceive to be a limitation in semver to describe some kinds of changes in some kinds of things in practical terms.

These replies are incredibly and bizarrely dogmatic. I never knew it'd be so hard to have a discussion about semver without people just going "semver is semver" as if that means something.

Re:Go Replaces Interface{} with 'Any' by msbarnett on Wednesday December 15, 2021 @12:03PM (#29568624)
> These replies are incredibly and bizarrely dogmatic. I never knew it'd be so hard to have a discussion about semver without people just going "semver is semver" as if that means something.

You seem to have misunderstood. We're not pointing out that "semver is semver", we're pointing out that semver as defined with respect to compilers, which is to say, the ability of existing code to run with a new version of the compiler, and what you "perceive to be a limitation in semver" are fundamentally in tension.

The only non-perf changes that would be allowed as non-breaking changes if we addressed what you perceive to be limitations in semver are precisely those changes which would be breaking in semver-as-it-exists, and those permitted in semver-as-it-exists are precisely those which you perceive as limitations.

Happy to discuss semver, but fundamentally the thing here is that what would address your perceived limitations is... the literal opposite of semver. Which is fine! But something not being its literal exact opposite isn't exactly a flaw in the thing itself; you simply want something else entirely.

Re:Go Replaces Interface{} with 'Any' by stormbrew on Wednesday December 15, 2021 @03:59PM (#29571550)
The dogmatism I'm perceiving here is at least in part that you're applying an extremely black and white approach to this. There are many possibilities between semver and "the opposite of semver", and there are options that exist along other axes from semver as well. The only way what you're saying here makes much sense to me is if you define "opposite of X" to be "anything that is not X", which is.. weird.

And again, I did not propose "the opposite of semver" or anything else. I said "some changes are poorly described by semver". It's a big leap from that to "I know exactly what you have in mind and it is every change is a major change." Which I... did not say anywhere?

Though, I do think that, as I mentioned elsewhere, this is approximately the net practical effect of using semver for things that have a principled opposition to breaking of backwards compatibility. If you never go to '2.0.0' then the '1.' part of '1.234234.0' is meaningless. Your version is just 234234.0 and you're playing the same game of pretend that '0.x' does in semver only with a bigger number. Again though, this is not me proposing that, it is me observing that the thing you're arguing against is possibly what's really happening anyways.

Re:Go Replaces Interface{} with 'Any' by msbarnett on Wednesday December 15, 2021 @04:54PM (#29572084)
My observation is merely that every additive change breaks the ability of new code to work with old compilers, and that it would be really, really weird to have a system in which you bump a major version because old code continues to work, but bump a minor when it would break or something.

If you "aren't proposing" that, then all you seem to be saying is "I think sometimes major versions should signal that they break compatibility with old code and sometimes they should signal that they maintain compatibility with old code because of some never-promised loss of reverse compatibility with new code on old compilers" which ... sounds uninteresting, unreliable, and frankly terrible from the standpoint of anyone who wants automated tooling to be able to make decisions based on signals in the version numbers (which, while not 100% reliable, is still a huge win over the old days of "versions can just be whatever, man" imo)

Re:Go Replaces Interface{} with 'Any' by naikrovek on Tuesday December 14, 2021 @08:54PM (#29561071)
doesn't matter how "big" of a change it is, it matters if it breaks anything. that's the whole point of semantic versioning.

also how is "big" even measured? meters? kilometers? it's immeasurable, which is why the rule is to update the version number based on what changes break existing code, because that can be measured

Re:Go Replaces Interface{} with 'Any' by randomswede on Thursday December 16, 2021 @10:46AM (#29579349)
Go code that requires language (or stdlib) features first present in Go v1.n will not compile with any version of Go 1.m, m <= n. There have been a few of these (modules, soft-launched in (IIRC) 1.11, there were one or a few in 1.15, now generics in 1.18).

But, the backwards compatibility guarantee is that code that worked with Go v 1.n will work with Go v 1.j, for j >= n.

Next para is based on my recollection of the discussion around generics.

Specifically for generics, any code that doesn't use generics is untouched by the presence of generics elsewhere. Code that is, in and of itself, not generic will, in most cases, being able to call functions that are declared generic without extra hassle (there are most probably a few cases where a type annotation on the function using generics would be required). Code using generic data types probably needs to type-annotate, but there may be cases where it's not necessary.