Currently ~0.y.z is the same as ^0.y.z, but I think this might not be such useful behaviour, and perhaps for 0.y.z versions it would be more useful to have ~0.y.z be the same as =0.y.z.
This would allow ^ and ~ to mean the same no matter the major version:
^ means "only allow SemVer compatible versions" i.e. "allow backwards-compatible new features"~ means "only allow bug-fixes" i.e "do not allow new features"This is what they currently mean for versions x.y.z when x > 0
But for versions or 0.y.z, where SemVer doesn't say anything, I believe "Julia SemVer" as encoded in Pkg says 0.1 and 0.2 can contain breaking changes, and 0.1.1 and 0.1.2 can contain new backwards-compatible features, and there is no way to encode "this just has a bug-fix" in 0.y.z versions. E.g. 0.1.1 -> 0.1.2 may contain only a bug-fix, but may contain a new non-breaking feature.
So I think it is more consistent to have
# no change to ^ behaviour
PkgA = "^0.2.3" # [0.2.3, 0.3.0)
PkgB = "^0.0.3" # [0.0.3, 0.0.4)
# proposed change to ~ behaviour for 0.y.z versions
PkgA = "~0.2.3" # [0.2.3, 0.2.3)
PkgB = "~0.0.3" # [0.0.3, 0.0.3)
The gain here is that there is consistent syntax ^ for "only non-breaking features", and ~ for "no new features" no matter the major version.
If you mean =, then why not use =?
The gain here is that there is consistent syntax ^ for "only non-breaking features", and ~ for "no new features" no matter the major version.
~ will now also mean "no bugfixes".
The problem is that I need to pay attention to what the major version is to get "no new features" behaviour. I suggest ~ should mean "no new features only bug-fixes", which is what it means for x.y.z with x>0 but currently not for x=0
i.e. i want consistent behaviour no matter the major version, but currently i have to use inconsistent syntax for that. I do not want = in all cases, I want "no new features", which means writing ~ for x>0, but = for x=0.
Note that there is no way for ~ to mean "only bug-fixes" becuase in 0.y.z there is no way to encode in the version number that the release contains only bug-fixes.
Obviously in 0.y.z land, only 2 interesting things can happen: y changes or only z changes. But we have 3 pieces of syntax to play with: ^, ~, =. So 2 out of 3 will end up signifying the same thing.
Currently ^ and ~ mean the same thing. I propose that it is more useful for ~ and = to mean the same thing. The benefit is a consistent syntax for "no new features" no matter the major version. (Or more generally, ^ and ~ having the same meaning no matter the major version).
If we interpret ~x.y.z to mean "only bug fixes" in the Julia convention then it should do the following:
~1.2.3 = [1.2.3, 1.3.0)~0.1.2 = [0.1.2, 0.2.0)~0.0.1 = [0.0.1, 0.0.2)I think that's what you meant, @nickrobinson251, but there may have been a typo since both of the closed/open version ranges you wrote are empty: [0.2.3, 0.2.3) and [0.0.3, 0.0.3).
Actually that's exactly what I am disputing 馃槅
I understand "only bug-fixes" to be a thing that cannot be represented by a version with a lead 0 (in Julia SemVer world).
0.1 goes to 0.2 if a breaking change is included, else it goes to 0.1.1. So 0.1.1 may contain only bug-fixes, or it may contain backwards-compatible new features, meaning there is no way to ensure we only get bug-fixes.
I understand "only bug-fixes" to be a thing that cannot be represented by a version with a lead 0 (in Julia SemVer world).
So 0.1.1 may contain only bug-fixes, or it may contain backwards-compatible new features
That's not how Julia itself used SemVer in the pre-1.0 world, e.g. 0.4.1 was a bugfix-only release. So before 1.0 there were only bugfix releases and breaking releases鈥攖here were no non-breaking feature releases. I've been meaning to write a blog post about this, perhaps today is a good day for that.
before 1.0 there were only bugfix releases and breaking releases鈥攖here were no non-breaking feature releases.
Hmmm, interesting! FWIW, in the 0.y.z world, i think breaking versus non-breaking is a more useful distinction than feature versus bug-fix, at least for packages -- perhaps for projects on the scale of Julia itself it's different, or perhaps I am wrong :)
The reasoning is pretty simple: if your project is mature enough to have non-breaking feature-adding releases, then its API is pretty stable and it's mature enough to have a non-zero major version number.
I think maybe the issue i'm running into is that adopting a "breaking v non-breaking" distinction is easier / more useful, partly becuase supporting multiple "breaking"-but-not-actually-breaking changes whenever a new feature or default changed is added is annoying for 2 reasons:
0.2.1, 0.3, 0.4, 0.5, 0.6, ... (https://github.com/JuliaLang/Pkg.jl/issues/843 would help here)Context is an ecosystem of 10s of packages, some of which have are adding many new features, as part of figuring out the right API.