Package versioning policy - Harmless type changes?

Dear all, the package versioning policy specifies that changing the type of any entity makes a change of the B number in A.B.C necessary. However, it seems to me that a small selection of type changes don't break dependent code. In particular, consider the following example, where I drop a Typeable class constraint: - foo :: Typeable a => AddHandler a -> NetworkDescription (Event a) + foo :: AddHandler a -> NetworkDescription (Event a) Can removing a type class constraint on a function break dependent code? Should I change the B number or just the C in version A.B.C when introducing this change? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com

On Thu, Sep 22, 2011 at 7:37 AM, Heinrich Apfelmus
- foo :: Typeable a => AddHandler a -> NetworkDescription (Event a) + foo :: AddHandler a -> NetworkDescription (Event a)
Can removing a type class constraint on a function break dependent code? Should I change the B number or just the C in version A.B.C when introducing this change?
This change would break only backwards compatibility. For example, suppose that the version with "Typeable a =>" is 0.1.2 and the version without is 0.1.3. Suppose that you have already released your version 0.1.3 when I create a package with the value: bar :: NetworkDescription (Event (Set a)) bar = ... foo ... Given that you are following the PVP, I would put the following constraint: Build-depends: foo >= 0.1 && < 0.2 However, if someone with an older version of foo installed on their system tried to install my package, they would get a type error, since I haven't put a "Typeable a =>" context on my bar. So, yes, that change can break some code. Is that change big enough to be considered harmful? I don't know =), probably not. Cheers, -- Felipe.

Hi, Am Donnerstag, den 22.09.2011, 08:32 -0300 schrieb Felipe Almeida Lessa:
On Thu, Sep 22, 2011 at 7:37 AM, Heinrich Apfelmus
wrote: Given that you are following the PVP, I would put the following constraint: Build-depends: foo >= 0.1 && < 0.2
However, if someone with an older version of foo installed on their system tried to install my package, they would get a type error, since I haven't put a "Typeable a =>" context on my bar.
would you? I think you would use foo >= 0.1.3 && < 0.2, because 0.1.3 is allowed to have API additions that are not in 0.1.2, so if you develop your library against 0.1.3, there is no guarantee that foo was not empty in 0.1.2. Under this interpretation, removing a constraint should be equivalent to an API addition, hence rule 2 on http://www.haskell.org/haskellwiki/Package_versioning_policy#Version_numbers ought to apply. Greetings, Joachim -- Joachim "nomeata" Breitner mail@joachim-breitner.de | nomeata@debian.org | GPG: 0x4743206C xmpp: nomeata@joachim-breitner.de | http://www.joachim-breitner.de/

Joachim Breitner wrote:
Felipe Almeida Lessa wrote:
Given that you are following the PVP, I would put the following constraint:
Build-depends: foo >= 0.1 && < 0.2
However, if someone with an older version of foo installed on their system tried to install my package, they would get a type error, since I haven't put a "Typeable a =>" context on my bar.
would you? I think you would use foo >= 0.1.3 && < 0.2, because 0.1.3 is allowed to have API additions that are not in 0.1.2, so if you develop your library against 0.1.3, there is no guarantee that foo was not empty in 0.1.2.
Under this interpretation, removing a constraint should be equivalent to an API addition, hence rule 2 on http://www.haskell.org/haskellwiki/Package_versioning_policy#Version_numbers ought to apply.
I like that point of view. In a sense, generalizing a type is literally equivalent to adding a new function to the API which can be used in new contexts. The only difference is that the new function has the same name as the old one. It's not entirely safe to generalize a type, though, due to issues with type classes and ambiguity. For instance, the generalization read :: Read a => String -> a - showDouble :: Double -> String + showDouble :: Floating a => a -> String will break the program foo :: String -> String foo = showDouble . read That said, is it true that *removing* a class constraint will never cause ambiguities? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com
participants (3)
-
Felipe Almeida Lessa
-
Heinrich Apfelmus
-
Joachim Breitner