Johan Tibell | 26 Feb 13:37 2014
Picon

PVP proposal: don't require major version bump when adding non-orphan instances

Hi all,

(This email is about trying to improve the PVP. If you think the PVP is a bad idea to begin with, please discuss that in a separate email thread.)

The PVP [1] states that

A.B is known as the major version number, and C the minor version number. When a package is updated, the following rules govern how the version number must change relative to the previous version:
  • If any entity was removed, or the types of any entities or the definitions of datatypes or classes were changed, or instances were added or removed, then the new A.B must be greater than the previous A.B. Note that modifying imports or depending on a newer version of another package may cause extra instances to be exported and thus force a major version change.
  • Otherwise, if only new bindings, types, classes or modules (but see below) were added to the interface, then A.B may remain the same but the new C must be greater than the old C.
  • Otherwise, A.B.C may remain the same (other version components may change).

Bumping the major version number often introduce a number of downstream changes, as package author need to loosen dependency constraints to allow the new package version to be used. This creates quite a bit of work for maintainers.

A particular onerous requirement is to have to bump the major version whenever you add a new instance. In spirit adding a new instances feels like adding a new function, like making an extension to the API, something ought to not break clients who use qualified imports and/or explicit import lists. For this reason and because of the cost to downstream maintainers, I've sometimes avoided bumping the major version in the past when adding a new instance.

However, introducing a new instance can only break other packages if those packages define orphan instance. Here's my reasoning:
  1. Assume there are no orphan instances.
  2. Package D defines a data type and package C defines a type class (it's possible that D=C.)
  3. An instance can only be added by either D or C.
  4. D and C cannot both depend on each other, so both cannot add the same instance.
  5. Another package O cannot add an instance (remember that orphans are disallowed).
  6. Since O cannot define an instance, there cannot be any conflicts in O if D or C (whichever depends on the other) adds an instance.
If this is true, we could change the first two PVP rules to (differences in italics):
  • If any entity was removed, or the types of any entities or the definitions of datatypes or classes were changed, or orphan instances were added or any instances were removed, then the new A.B must be greater than the previous A.B. Note that modifying imports or depending on a newer version of another package may cause extra instances to be exported and thus force a major version change.
  • Otherwise, if only new bindings, types, classes, non-orphan instances, or modules (but see below) were added to the interface, then A.B may remain the same but the new C must be greater than the old C.
and add the following clarifying sentence:

If a package defines an orphan instance, it must depend on the minor version of the packages that define the data type and the type class to be backwards compatible. For example, build-depends: mypkg >= 2.1.1 && < 2.1.2.

I believe this would result in less work for maintainers.


Discussion period: 3 weeks.

-- Johan

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries

Gmane