Why upper bound version numbers?

Oleg Grenrus oleg.grenrus at iki.fi
Thu Jun 9 11:28:20 UTC 2016

My five cents:

There is discussion/work in Cabal dev about splitting the solver out. [1] I hope that at the end, there will be functionality that you can construct build/install plan by whatever means and use cabal functionality to execute it.

Another functionality brought by work on haskell-security is that 01-index.tar.gz is append only file, so it’s “easy” to travel back in time in Hackage history.

Combining those one can run an experiment, on how much
- existing upper bounds prevent cabal from finding working install-plan; and how this change over time, because of maintainers activity.
- non-existing upper bounds prevent found install-plan to compile properly; and how this change over time, because of a) maintainers own activity, b) Hackage trustee activity
- other stats

Until quantitative report justifying that upper bounds are clearly bad-idea, I would not propose any dramatical changes to how default solver works or Cabal-definition-format spec. With own solvers it would be easy to experiment and provide own metadata.

As Hackage Trustee I do see much more full-of-red (failed builds) matrices on matrix.h.h.o than dark green ones (no install plan).
Unfortunately only my gut feeling, no hard numbers but, but GHC <7.4/7.6 tends to be often red (because of base ==4.*, or base <5), or there are full lines of red because newer version of dependency causes breakage (which is no upper-bounds)

For example. fast-logger introduced new type alias and new functionality in System.Log.FastLogger in minor version 2.4.4 [3]:

--- Diff for | 2.4.3 → 2.4.4 | ---

+ System.Log.FastLogger.Date
  + type FormattedTime = ByteString
  + type TimeFormat = ByteString
  + newTimeCache :: TimeFormat -> IO (IO FormattedTime)
  + simpleTimeFormat :: TimeFormat
  + simpleTimeFormat' :: TimeFormat
× System.Log.FastLogger
  + type FastLogger = LogStr -> IO ()
  + LogCallback :: (LogStr -> IO ()) -> (IO ()) -> LogType
  + LogFile :: FilePath -> BufSize -> LogType
  + LogFileAutoRotate :: FileLogSpec -> BufSize -> LogType
  + LogNone :: LogType
  + LogStderr :: BufSize -> LogType
  + LogStdout :: BufSize -> LogType
  + data LogType
  + type TimedFastLogger = (FormattedTime -> LogStr) -> IO ()
  + newFastLogger :: LogType -> IO (FastLogger, IO ())
  + newTimedFastLogger :: (IO FormattedTime) -> LogType -> IO (TimedFastLogger, IO ())
  + withFastLogger :: LogType -> (FastLogger -> IO a) -> IO ()
  + withTimedFastLogger :: (IO FormattedTime) -> LogType -> (TimedFastLogger -> IO a) -> IO ()
× System.Log.FastLogger.File
  × New: check :: FilePath -> IO ()
    Old: check :: FileLogSpec -> IO ()

[+ Added] [- Removed] [× Modified] [· Unmodified]

And according to PVP you can do it, bumping only minor version. (The change in System.Log.FastLogger.File is breaking change, so it should been major bump, but our example holds even it was 2.4.4 -> 2.5)

wai-logger package depends on fast-logger, and broke after new fast-logger release [4] because of:
- doesn’t have upper-bounds
- import(ed) modules improperly [5]

The new version was fixed immediately, so I suspect that whetever the issue were about breakage or restrictive-upper bounds (pinged from Stackage) it would been fixed as fast.

Yet now there is still lot’s of red in the matrix [6]. It’s highly unlikely that old versions would be picked by solver, but not impossible, happened to me, ekg-json picked very old aeson version (well again, no bounds there!) and broke. [7]

To summarise this example, I’d rather make PRs to relax version bounds, then try to guess what bounds I have to adjust so I get working install plan.

And to conclude,
- Please setup CI, e.g. using Herbert’s script [8]. It’s very easy!
- Have the base bounds restricting GHC’s to ones you test.
- Contributing (i.e. to bump version bounds) would be extremely easy for others and you.

Herbert is also very fast to make packages for newer (even unreleased version of GHC), so we had ability to test and fix! many packages before GHC-8.0 was officially released making adaptations as early as this year’s January.

- Oleg

- [1]: https://github.com/haskell/cabal/pull/3222
- [2]: http://matrix.hackage.haskell.org/packages see red-alert tag
- [3]: http://hackage.haskell.org/package/fast-logger-2.4.4/docs/System-Log-FastLogger.html
- [4]: https://github.com/kazu-yamamoto/logger/issues/88
- [5]: https://wiki.haskell.org/Import_modules_properly
- [6]: http://imgur.com/bTYI8KC
- [7] https://github.com/tibbe/ekg-json/pull/3
- [8] https://github.com/hvr/multi-ghc-travis

> On 09 Jun 2016, at 12:22, Jeremy . <voldermort at hotmail.com> wrote:
> Versions of package dependencies can be categorised into 5 sets:
> D1) Versions which the maintainer has tested and found to work
> D2) Versions which the maintainer has not tested but expects to work
> D3) Versions which the maintainer has tested and found to not work
> D4) Versions which the maintainer has not tested but expects to not work
> D5) Everything else
> Cabal, however, only knows of 3 sets:
> C1) Versions which satisfy build-depends
> C2) Versions which satisfy build-depends with --allow-newer
> C3) Everything else
> The problem arises from the fact that the D sets to not map well onto the C sets, even after combining D1&D2 and D3&D4. Perhaps this could be solved with a new .cabal property, breaks-with. The solver will then prefer packages in this order:
> 1) Versions that satisfy build-depends
> 2) Versions that are not in breaks-with, unless a flag such as --strict-build-depends is applied
> This may also lead to clearer build-depends, as instead of multiple ranges with gaps to skip know broken versions, build-depends can list a single range, and breaks-with can list the bad versions.
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 842 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20160609/8d9ea789/attachment.sig>

More information about the ghc-devs mailing list