Relaxin the PVP with regards to adding instances

Michael Sloan mgsloan at gmail.com
Tue Sep 11 19:04:38 CEST 2012


On Tue, Sep 11, 2012 at 5:32 AM, Ben Millwood <haskell at benmachine.co.uk> wrote:
> On Tue, Sep 11, 2012 at 6:14 AM, Michael Sloan <mgsloan at gmail.com> wrote:
>> Glad to hear that you agree that it's consistent!  This would make the
>> PVP simpler.
>>
>> I've been thinking, there's still a way to retain the property that
>> you can specify version bounds which retain compilation, even with
>> orphan instances.  If your package really needs to add an instance to
>> a datatype / class exported by some dependency, then you can put an
>> upper limit on the minor version.  Harsh, I know, but orphans muck
>> things up any way you slice it.
>>
>> This means that any orphans you use, you'd need to explicitly depend
>> on an A.B.C upper-bounded version of the packages that define the
>> datatypes (and classes, if you're being entirely correct), and not
>> consume them through something that re-exports them.  Ideally, this
>> could be mechanically checked.
>
> This seems sensible. However, in case this wasn't already clear, it
> means when you /add/ an orphan instance, you still need a major
> version bump: suppose I depend on package A and package B and have an
> orphan for a type in package B, then you suggest I depend on
> package-B-minor and package-A-major – so if package A adds an orphan
> instance, they need to make their version bump major to stop me from
> breaking.

I actually didn't write down what I meant to - instead of "any orphans
you use" --> "any orphans you define".  Using orphans does not cause
finer grained upper bounds.

Hmm, I hadn't thought of what you're pointing out!  So, the way to get
the properties I was going for, even with orphans, is that as soon as
you define an orphan instance, you must specify minor bounds on every
package that could realistically want to define their own orphans.
Definitely not ideal!  I guess the alternative is the "instance
manifest" solution, and have Cabal use them for resolution (also hairy
and troublesome)..

>> The maintenance of this kind of stuff can be reduced by centralizing
>> stuff in orphans package  (does Hackage 2.0 provide a way to
>> email-subscribe to a package? might also be good for maintaining these
>> sorts of things).  If a central orphans package isn't acceptable, then
>> you're probably not writing a library for general consumption anyway,
>> so upper limits on minor bounds wouldn't be problematic.
>
> Whether or not centralised orphans are appropriate really depends on
> why the orphans exist in the first place. If they are just because the
> original package deemed those instances not necessary, then fine
> (although they should really be put in the original package). But
> frequently they are because there is a class in module A and a type in
> module B that have a sensible instance, but neither the package
> containing A nor B know about each other (or there is no natural
> direction for the dependency to go). In that case, you really want a
> package per A,B pair, since otherwise you're going to bring in
> irrelevant dependencies.

Yup, I can agree to that!  A naming + namespace convention for this
variety of package might be good, for discoverability.

-Michael

>
>> -Michael
>>
>> On Thu, Sep 6, 2012 at 4:24 AM, Simon Marlow <marlowsd at gmail.com> wrote:
>>> On 06/09/2012 01:16, Johan Tibell wrote:
>>>>
>>>> Hi all,
>>>>
>>>> The PVP says:
>>>>
>>>> "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:
>>>>
>>>> 1. 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."
>>>>
>>>> The part about adding instances and the one about modifying imports
>>>> makes it hard to follow the PVP. Bumping the major version number is a
>>>> quite disruptive change for your users if they use upper bounds on
>>>> their dependencies. Minor version bumps are not nearly as disruptive
>>>> as you can you can depend on x.y.* as long as you only use qualified
>>>> imports and/or explicit import lists.
>>>>
>>>> Assuming no one uses orphan instances, adding instances is always safe
>>>> because you can only add instances for types from packages you depend
>>>> on, which means that they can't be depending on your package in turn
>>>> and have defined a non-orphan instance for a type or class defined in
>>>> your package.
>>>>
>>>> I suggest that the rule be changed to not require a major version bump
>>>> if instances are added.
>>>
>>>
>>> Yes, I think this is reasonable.  The client already has some obligations if
>>> they want to be independent of minor versions: they have to use explicit
>>> import lists.  So adding another obligation, no orphan instances, is
>>> consistent with this and shouldn't cause problems in the majority of cases.
>>>
>>> Cheers,
>>>         Simon
>>>
>>>
>>>
>>>
>>>> P.S. I believe the same reasoning can be applied to the import part of
>>>> the rule above.
>>>>
>>>> -- Johan
>>>>
>>>> _______________________________________________
>>>> Libraries mailing list
>>>> Libraries at haskell.org
>>>> http://www.haskell.org/mailman/listinfo/libraries
>>>>
>>>
>>>
>>> _______________________________________________
>>> Libraries mailing list
>>> Libraries at haskell.org
>>> http://www.haskell.org/mailman/listinfo/libraries
>>
>> _______________________________________________
>> Libraries mailing list
>> Libraries at haskell.org
>> http://www.haskell.org/mailman/listinfo/libraries



More information about the Libraries mailing list