# Alternatives to PVP for Alpha / Exploratory packages?

**URL:** <https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612>\
**Category:** Uncategorized\
**Created:** [September 18, 2023, 5:09am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612 "2023-09-18T05:09:06Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Liamzy](https://avatars.discourse-cdn.com/v4/letter/l/50afbb/32.png) [@Liamzy](https://discourse.haskell.org/u/Liamzy)\
**Post date:** [September 18, 2023, 5:09am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/1 "2023-09-18T05:09:06Z")

</div>

Trying to develop an alpha / exploratory lib, I’ve found that PVP is a complete pain in the ass because it implies that I have to completely solidify the API while I’m still intending a package for testing purposes.

If I want to completely refactor the package and change the API, or do some major changes, I can’t, because it’ll bump up my version numbers tremendously.

Are there any alternatives to PVP for “screwing around packages” that don’t involve putting it up on Github / Codeberg? If we’re talking Github or Codeberg, even then it’d be useful to have an alt-PVP for messing around.

---

<div class="post-metadata">

**Author:** ![hasufell](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/hasufell/32/1250_2.png) [@hasufell](https://discourse.haskell.org/u/hasufell)\
**Post date:** [September 18, 2023, 5:27am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/2 "2023-09-18T05:27:35Z")

</div>

Hackage has candidates: [Uploading packages and package candidates | Hackage](https://hackage.haskell.org/upload#candidates)

If you have suggestions for changing PVP, you can write a proposal: [Issues · haskell/pvp · GitHub](https://github.com/haskell/pvp/issues)

Keep in mind that it would be a new version of the spec and likely have to be very well thought through to even get a chance to be remotely accepted.

---

<div class="post-metadata">

**Author:** ![DavidB](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/davidb/32/3616_2.png) [@DavidB](https://discourse.haskell.org/u/DavidB)\
**Post date:** [September 18, 2023, 6:51am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/3 "2023-09-18T06:51:34Z")

</div>

What you are looking for is probably something like §4 of the SemVer specification: [Semantic Versioning 2.0.0 | Semantic Versioning](https://semver.org/#spec-item-4)

> 1. Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.

The PVP spec that Hackage follows is older than SemVer, and doesn’t provide a similar clause, sadly.

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [September 18, 2023, 7:13am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/4 "2023-09-18T07:13:24Z")

</div>

> [@Liamzy](#):
>
> If I want to completely refactor the package and change the API, or do some major changes, I can’t, because it’ll bump up my version numbers tremendously.

What’s wrong with bumping the version numbers tremendously? In fact, you’re going to bump your version numbers tremendously either way (once for each release) it’s just a question of which component you bump. Why is it a problem to bump `x` tremendously but not `y`, in `w.x.y.z`?

---

<div class="post-metadata">

**Author:** ![Liamzy](https://avatars.discourse-cdn.com/v4/letter/l/50afbb/32.png) [@Liamzy](https://discourse.haskell.org/u/Liamzy)\
**Post date:** [September 18, 2023, 7:20am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/5 "2023-09-18T07:20:57Z")

</div>

I’d rather reserve w for total rewrites of API, and naively, I’d assume a 0.x version is a prototype, while a 1 version is finished to some degree.

Implicitly, with your suggestion, I’d end up publishing 20.0.0.0, which to the outside user implies that it’s much more mature than it is.

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [September 18, 2023, 7:24am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/6 "2023-09-18T07:24:53Z")

</div>

With my suggestion you’d end up with `0.20.0.0`, which seems exactly what you want, unless I’m somehow missing something …

---

<div class="post-metadata">

**Author:** ![tdammers](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tdammers/32/3319_2.png) [@tdammers](https://discourse.haskell.org/u/tdammers)\
**Post date:** [September 18, 2023, 8:31am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/7 "2023-09-18T08:31:06Z")

</div>

You don’t need to take version numbers seriously until you actually release your package, you know. While it’s in an exploratory stage, you can just keep it at 0.1.0, even with PVP, and if you have other code that depends on it, just pull it in from git (doesn’t have to be github, you can host your git repo anywhere cabal can find it), and use commit hashes to pin your dependencies to an exact version.

Once you release it, bump the version number; you can still be as experimental as you want on the git version, you just need to bump the version number correctly when you make the next (Hackage) release, and you only need to worry about the current release and the previous one when determining the correct PVP version number. The in-between “experimental” versions may not have the correct version number, but that’s OK, because you’re not releasing them into the Hackage / Cabal ecosystem, so they will never be selected by the Cabal solver unless you explicitly ask for them (via, again, a git repo dependency, which you should pin to an exact commit hash).

---

<div class="post-metadata">

**Author:** ![hasufell](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/hasufell/32/1250_2.png) [@hasufell](https://discourse.haskell.org/u/hasufell)\
**Post date:** [September 18, 2023, 10:42am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/8 "2023-09-18T10:42:50Z")

</div>

That’s actually a rather confusing part of semver. It doesn’t exactly define what “stable” means. If my API is unstable, can I release breaking changes under a patch version increment? It doesn’t say. If not, what information does section 4 even convey?

Some libraries go through “unstable” API phases late in their lifetime.

---

<div class="post-metadata">

**Author:** ![wiz](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/wiz/32/2408_2.png) [@wiz](https://discourse.haskell.org/u/wiz)\
**Post date:** [September 18, 2023, 11:11am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/9 "2023-09-18T11:11:47Z")

</div>

But candidates can’t be added as deps, can they?

I think you can add a tarball URL, but then the URL would point to a mutable source, and that is problematic.

---

<div class="post-metadata">

**Author:** ![Liamzy](https://avatars.discourse-cdn.com/v4/letter/l/50afbb/32.png) [@Liamzy](https://discourse.haskell.org/u/Liamzy)\
**Post date:** [September 18, 2023, 1:10pm UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/10 "2023-09-18T13:10:54Z")

</div>

The problem with the 0.20.0.0 solution, is, well: bytestring, which I think most people consider stable and mature, is on 0.12.0.0.,

I guess it’s pretty presumptuous of me, but it seems as though it might be viable to amend PVP and the system surrounding it; i.e, allow a single-digit alphanumeric character in the PVP version code.

X could stand for experimental (quickly changing API), U could stand for “unmaintained”, i.e, it’s finished on fork-it-or-leave-it support, and other particular codes for “unusual” package versioning states.

---

<div class="post-metadata">

**Author:** ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)\
**Post date:** [September 18, 2023, 1:59pm UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/11 "2023-09-18T13:59:43Z")

</div>

Ah, I see. So you don’t just want a policy that you can apply to your own packages, but you want a policy that’s shared between all Haskell packages? The latter’s much harder of course!

---

<div class="post-metadata">

**Author:** ![Liamzy](https://avatars.discourse-cdn.com/v4/letter/l/50afbb/32.png) [@Liamzy](https://discourse.haskell.org/u/Liamzy)\
**Post date:** [September 18, 2023, 2:22pm UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/12 "2023-09-18T14:22:34Z")

</div>

Well, it’s just idle speculation; I have lots of that if that’s what you’re looking for.

---

<div class="post-metadata">

**Author:** ![brandonchinn178](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/brandonchinn178/32/5103_2.png) [@brandonchinn178](https://discourse.haskell.org/u/brandonchinn178)\
**Post date:** [September 18, 2023, 3:31pm UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/13 "2023-09-18T15:31:20Z")

</div>

FWIW You can depend directly on git repos in cabal.project or stack.yaml. So if it’s just exploratory for use in another project you control, you could not publish at all and just depend on the git repo at a commit

---

<div class="post-metadata">

**Author:** ![Bodigrim](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/bodigrim/32/1457_2.png) [@Bodigrim](https://discourse.haskell.org/u/Bodigrim)\
**Post date:** [September 18, 2023, 6:12pm UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/14 "2023-09-18T18:12:18Z")

</div>

Hackage is a permanent storage, one should not release stuff there just to experiment on. As @brandonchinn178 suggests, use `cabal.project` / `stack.yaml` to specify dependencies via Git repository.

That said, you can version a package as 0.20230901, 0.20230918, 0.20231001, etc. This way you comply with PVP fully, but also do not make a false impression of being well-established.

---

<div class="post-metadata">

**Author:** ![chreekat](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/chreekat/32/2669_2.png) [@chreekat](https://discourse.haskell.org/u/chreekat)\
**Post date:** [September 19, 2023, 11:43am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/15 "2023-09-19T11:43:08Z")

</div>

> [@Liamzy](#):
>
> I’d rather reserve w for total rewrites of API, and naively, I’d assume a 0.x version is a prototype, while a 1 version is finished to some degree.

Perennial reminder that, for better or worse, PVP treats 0.x as a _major version_. (Bad for optics in my opinion, and cause of considerable confusion given the extremely wide spread of SemVer at this point in history.)

---

<div class="post-metadata">

**Author:** ![andreabedini](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/andreabedini/32/2201_2.png) [@andreabedini](https://discourse.haskell.org/u/andreabedini)\
**Post date:** [September 20, 2023, 12:20am UTC](https://discourse.haskell.org/t/alternatives-to-pvp-for-alpha-exploratory-packages/7612/16 "2023-09-20T00:20:42Z")

</div>

It might be worth pointing out that SemVer main innovation was to remove from version numbers any meaning other than API compatibility. I.e. the only “semantic” is whether a new version change the API. Following this approach, there’s nothing “major” about a major bump; perhaps we should try to avoid the major/minor terminology.

Does anybody remember the _romantic_ and the _sentimental_ versioning comebacks? 😌
