Pkg.jl: Should compat `~0.y.z` be the same as `=0.y.z`?

Created on 5 Jul 2019  路  9Comments  路  Source: JuliaLang/Pkg.jl

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.

All 9 comments

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:

  1. currently we have to list every version: 0.2.1, 0.3, 0.4, 0.5, 0.6, ... (https://github.com/JuliaLang/Pkg.jl/issues/843 would help here)
  2. When the main package changes, it's not easy to check if some of these dependency versions should be removed from the compat list (https://github.com/JuliaLang/Pkg.jl/issues/1062 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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

moustachio-belvedere picture moustachio-belvedere  路  3Comments

GregPlowman picture GregPlowman  路  3Comments

dpsanders picture dpsanders  路  3Comments

cscherrer picture cscherrer  路  3Comments

StefanKarpinski picture StefanKarpinski  路  3Comments