proposal: in base, for Data.Version, change the meaning of comparisons

Proposal: that values of the type Data.Version.Version should compare
equal, by ignoring trailing zeros.
Thus 1.2.0 == 1.2, rather than 1.2.0 > 1.2
Regards,
Malcolm
----
New patches:
[In Data.Version, make equality comparisons independent of trailing zeros.
Malcolm.Wallace@cs.york.ac.uk**20071025161240] {
hunk ./Data/Version.hs 122
- v1 == v2 = versionBranch v1 == versionBranch v2
+ v1 == v2 = branchEq (versionBranch v1) (versionBranch v2)
hunk ./Data/Version.hs 125
+ where
+ branchEq :: [Int] -> [Int] -> Bool
+ branchEq [] [] = True
+ branchEq vs [] = all (==0) vs
+ branchEq [] vs = all (==0) vs
+ branchEq (v:vs) (w:ws) = v==w && branchEq vs ws
hunk ./Data/Version.hs 133
- v1 `compare` v2 = versionBranch v1 `compare` versionBranch v2
-
+ v1 `compare` v2 = versionBranch v1 `cmpBranch` versionBranch v2
+ where
+ cmpBranch [] [] = EQ
+ cmpBranch vs [] | all (==0) vs = EQ
+ | otherwise = GT
+ cmpBranch [] vs | all (==0) vs = EQ
+ | otherwise = LT
+ cmpBranch (v:vs) (w:ws) | v==w = cmpBranch vs ws
+ | otherwise = compare v w
+
}
Context:
[Fix doc building with Haddock 0.9
Simon Marlow

Malcolm Wallace wrote:
Proposal: that values of the type Data.Version.Version should compare equal, by ignoring trailing zeros. Thus 1.2.0 == 1.2, rather than 1.2.0 > 1.2
I see advantages and disadvantages. Advantages: * matches intuitive understanding of versions * lets us drop trailing zeroes in version numbers Disadvantages: * version ordering is slightly harder to explain Is there a precedent anywhere else for doing this?
[In Data.Version, make equality comparisons independent of trailing zeros. Malcolm.Wallace@cs.york.ac.uk**20071025161240] { hunk ./Data/Version.hs 122 - v1 == v2 = versionBranch v1 == versionBranch v2 + v1 == v2 = branchEq (versionBranch v1) (versionBranch v2) hunk ./Data/Version.hs 125 + where + branchEq :: [Int] -> [Int] -> Bool + branchEq [] [] = True + branchEq vs [] = all (==0) vs + branchEq [] vs = all (==0) vs + branchEq (v:vs) (w:ws) = v==w && branchEq vs ws hunk ./Data/Version.hs 133 - v1 `compare` v2 = versionBranch v1 `compare` versionBranch v2 - + v1 `compare` v2 = versionBranch v1 `cmpBranch` versionBranch v2 + where + cmpBranch [] [] = EQ + cmpBranch vs [] | all (==0) vs = EQ + | otherwise = GT + cmpBranch [] vs | all (==0) vs = EQ + | otherwise = LT + cmpBranch (v:vs) (w:ws) | v==w = cmpBranch vs ws + | otherwise = compare v w + }
Wouldn't the implementation be simpler if you added a dropTrailingZeros function, and just applied it before comparing? That would more obviously match the informal description too. Cheers, Simon

Proposal: that values of the type Data.Version.Version should compare equal, by ignoring trailing zeros. Thus 1.2.0 == 1.2, rather than 1.2.0 > 1.2
Simon Marlow
I see advantages and disadvantages. Advantages: * matches intuitive understanding of versions * lets us drop trailing zeroes in version numbers Disadvantages: * version ordering is slightly harder to explain
Pretty much, yes. Although arguably the disadvantage is not so bad, since currently one has to explain why 1.2.0 is _not_ the same as 1.2.
Is there a precedent anywhere else for doing this?
I could point to ordinary decimal notation, where 1.2000 == 1.2. http://en.wikipedia.org/wiki/Trailing_zero Perl has a related notion of implicit zero-extension in the "version" pod: http://search.cpan.org/~jpeacock/version-0.74/lib/version.pod Microsoft's .NET Framework seems to ignore trailing zeros in versions: http://www.cyscape.com/products/bhawk/docs/BrowserHawk/CompareVersions_Metho... http://msdn2.microsoft.com/en-us/library/d5cd9b2c.aspx wxWidgets release numbers sometimes omit trailing zeros: http://www.wxwidgets.org/manuals/stable/wx_backwardcompatibility.html I found proposals to ignore trailing zeros in version comparisons within OpenOffice, Python distutils, and Drupal: http://extensions.openoffice.org/servlets/ReadMsg?list=dev&msgNo=212 http://mail.python.org/pipermail/distutils-sig/2007-September/008324.html http://vbdrupal.org/forum/showthread.php?p=591
Wouldn't the implementation be simpler if you added a dropTrailingZeros function, and just applied it before comparing?
Yes, that is another possible implementation. It involves traversing both version structures twice rather than once (but I don't suppose the slight efficiency loss would ever be noticable). Regards, Malcolm

Malcolm Wallace wrote:
Proposal: that values of the type Data.Version.Version should compare equal, by ignoring trailing zeros. Thus 1.2.0 == 1.2, rather than 1.2.0 > 1.2
Simon Marlow
wrote: I see advantages and disadvantages. Advantages: * matches intuitive understanding of versions * lets us drop trailing zeroes in version numbers
maybe, but the trailing zeroes have some effect so far...
Disadvantages: * version ordering is slightly harder to explain
Pretty much, yes. Although arguably the disadvantage is not so bad, since currently one has to explain why 1.2.0 is _not_ the same as 1.2.
* it means (==) is not extensional equality for Versions (e.g. (vA == vB && not (show vA == show vB))... then again, this is already true if versionTags is used for anything. (show version), and especially the appending-the-date, depend on how many trailing zeroes are in a particular version so it is likely to be ill-defined, if versions are used as Map keys, which one is stored as the key... not too bad, but people tend to think of (==) as extensional equality most of the time, I think
Is there a precedent anywhere else for doing this?
okay, the precedent you demonstrated seems like an advantage if we do this, we should find a way not to depend on the number of trailing zeroes for anything? note that, version-wise, unless we imagine (rightly enough) that negative version numbers are forbidden, this would make Version not even obey the Ord laws; currently Prelude Data.Version> Version [1] [] < Version [1,-1] [] True Prelude Data.Version> Version [1,-1] [] < Version [1,0] [] True Prelude Data.Version> Version [1] [] < Version [1,0] [] True #by transitivity; but the proposal would defeat that Actually not if [1,-1] < [1], which would be plausible to be part of the implicit trailing zeroes concept Isaac

On 2007-10-26, Isaac Dupree
Actually not if [1,-1] < [1], which would be plausible to be part of the implicit trailing zeroes concept
This should clearly be true, if we want to argue from positional number systems. -- Aaron Denney -><-

On Fri, Oct 26, 2007 at 11:46:34AM +0100, Malcolm Wallace wrote:
Simon Marlow
wrote: Is there a precedent anywhere else for doing this?
I could point to ordinary decimal notation, where 1.2000 == 1.2. http://en.wikipedia.org/wiki/Trailing_zero
Well, I don't think anyone is arguing that Cabal should think that 1.2000 == 1.2.
Perl has a related notion of implicit zero-extension in the "version" pod: http://search.cpan.org/~jpeacock/version-0.74/lib/version.pod
I haven't read the documentation properly to know exactly what the logic is behind this definition of versions (is it trying to DTRT for historical perl version numbers?), but it looks pretty scary: $ perl -Mversion -de 1 [...] DB<1> p version->new(0.2) > version->new(0.1) 1 DB<2> p version->new(0.2.0) > version->new(0.1) DB<3> p version->new(0.2)->normal v0.200.0 DB<4> p version->new(0.2.0)->normal v0.2.0 DB<5>
[...]
I don't think software release numbers are very compelling examples, unless they release both x and x.0 (in which case they presumably are not going to be considered equal). For what it's worth, dpkg thinks x.0 > x: $ dpkg --compare-versions 1.0 gt 1 && echo yes yes I believe rpm does too, although I can't find an easy way to ask it or a reliable description of what the algorithm does. I also can't immediately find any details on what Gentoo, *BSD, etc think. Personally I don't have strong feelings either way, although I lean slightly towards the current definition. I'd like x.0 to be the same as x, but Cabal's snapshot version feature (append .$date to the version number) can tell them apart. Also, I believe the code is simpler for the current definition. Thanks Ian

On Sat, 2007-10-27 at 01:59 +0100, Ian Lynagh wrote:
I believe rpm does too, although I can't find an easy way to ask it or a reliable description of what the algorithm does. I also can't immediately find any details on what Gentoo, *BSD, etc think.
Most details on gentoo package versions are explained here: http://www.gentoo.org/proj/en/devrel/handbook/handbook.xml?part=3&chap=1#doc_chap3 It doesn't say if trailing .0 version components are significant but from a quick experiment with dummy packages foo-0.1 and foo-0.1.0 Gentoo does consider 0.1.0 > 0.1. That is, it considers version 0.1.0 to be an upgrade on 0.1 where as 0.1 is a re-install. Duncan
participants (6)
-
Aaron Denney
-
Duncan Coutts
-
Ian Lynagh
-
Isaac Dupree
-
Malcolm Wallace
-
Simon Marlow