apple / swift-numerics

Advanced mathematical types and functions for Swift

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Meaning of pre‐semantic versioning?

SDGGiesbrecht opened this issue · comments

I’m curious what is meant by the version numbers of releases. Specifically, what version constraints should clients be specifying in the manifest?

The read‐me recommends from: "0.0.7". Does that mean everything < 1.0.0 is supposed to be source‐compatible with 0.0.7, or is that a typo?

Releases recently switched from 0.0.x to 0.x.x. Does that indicate an intent to have all 0.1.x releases source‐compatible?

Which constraint should clients use? .exact("0.0.7"), .upToNextMinor(from: "0.1.0"), or from: "0.1.0"?

Don't read too much into it. The readme simply hasn't been updated. I'll be using 0.x.0 for normal tags from now on, and 0.x.y for any bug fixes.

(Readme is now updated on main.)

But is from: "0.1.0" actually advisable? It implies that 0.999.999 will still be source compatible.

That depends strongly on what someone's needs are. If you need a hard source compatibility guarantee, no matter what, you should pin to a version (this is true of almost every project, though, regardless of semver; semver is a reassuring fiction that we allow ourselves to believe).

For most users, yes, from: "$(current version)" is probably most appropriate; while we don't have a hard source compatibility guarantee yet, breaking changes have been extremely rare, will continue to be, and will always have a substantial migration window when possible.

This is not about the frequency of changes or the length of the migration window.

from: "0.1.0" instructs SwiftPM to select any (in practice the greatest) version which satisfies 0.1.0 ≤ v < 1.0.0; it is a declaration of simultaneous compatibility with all such versions. A client who does that will break as soon as swift‐numerics releases a version satisfying that constraint but not attempting to be source compatible. (This is not a job for pins either; they are deliberately not inherited.)

from: makes sense when the major version is 1 or greater, because source compatibility is inherent to the semver contract. However, major version 0 is semantically void in the semver standard, and so it can be used in a free‐for‐all fashion. Normally, only .exact() makes any sense when depending on a 0 version.

However, because 0 has no formal meaning, a vendor is free to assign its own meaning and communicate it to clients. Many vendors choose to treat the version components as shifted one slot to the right, guaranteeing that patches are source‐compatible. Part of that communication involves the instructions for declaring the dependency, and Swift packages doing this usually tell clients to declare .upToNextMinor(from: "0.1.0"). In swift‐numerics’ read‐me, the from: "0.1.0" comes across as an indicator that future 0 versions will all be compatible.

But from your description in this thread, it sounds like clients should never use from: "0.1.0", because source compatibility isn’t really being considered in swift‐numerics’ versioning. I strongly recommend changing the read‐me to say .exact("0.1.0") instead, otherwise you are instructing clients to shoot themselves in the foot.

However, major version 0 is semantically void in the semver standard, and so it can be used in a free‐for‐all fashion.

Can be, but is not. The fundamental problem here is that Swift Numerics is still gaining significant API surface area. Individual API are stable within a tag or two of release, but because we keep adding new API (and will continue to be doing so for a long while to come), the project as a whole is not (hence 0.x.y). Semver is too blunt of a hammer to handle this situation well.

We could, I suppose, work around this by introducing new features in a.x.y and bumping to (a+1).0.0 once stabilized, but that's fairly weird (and implies the possibility of breaking changes in stabilized modules, which doesn't actually help anyone).

We could also work around it by splitting SN into lots of little projects, but that has its own complications (that said, this might actually be the best solution long-term--certainly it would align things more with the aspirations of semver).

In the meantime, from: is the most appropriate choice. In practice, no one has yet been shot in the foot, and I don't expect anyone will be.

We’ll have to agree to disagree. I assume the issue can be closed?