
On 25.10 09:06, Brian Smith wrote:
Please point out some cases where splitting a package into multiple packages would lead to recursive package dependencies so I can study them.
There are two logging handlers: logger-null and logger-db. Logger-db depends on a database connection. Database connections are provided by postgresql and mysql modules which both depend on a logger being selected. Thus build-depends: logger-null: logger-db: db-any db-any: postgresql || mysql postgresql: logger-db mysql: logger-db
I understand that this would increase the number of packages. But, if it would increase the number of packages 10x, then that means that the original package could be configured with 10 different subsets of functionality. In that case, saying "Build-depends: foo" for that package foo would be almost meaningless. You would need to add some kind of more specific dependency like "Build-depends: foo (Foo.Bar.A, Foo.Bar.C, Foo.Bar.D)" to indicate what modules you need from foo.
16 different subsets are created by e.g. 4 binary choices. e.g. in network-alt I have one choice with 4 alternatives (the backend) and the choice whether to use fps. Then there is debugging. That is 4*2*2 = 16 choices. And only the FPS one affects API.
Packages should be created in such a way that the set of things exported from the package should not change based on configuration. If some features are only valid under one configuration, then they should be factored out into a seperate module and then a seperate package. For example, GHC-specific features should be factored out into a separate package, Windows-specific features should be factored out into a separate package, etc. More-or-less, that is how the hierarchical libraries are designed at the module level.
Except this is not true even for the base-package. See e.g. Control.Concurrent. Another problem is that they usually use internals of the package that one does not which to export.
If I build package foo with base 1.0, then I am going to be missing some features from it. The dependency "foo >= 2.0" doesn't fully describe the dependency. We could change it to " foo >= 2.0, base >= 1.1," but I'm not sure that means "I depend on foo 2.0 or later being built with base 1.1 or later" and furthermore, it means that packages' dependencies are not self-contained.
And package authors should take care on not doing evil things. There are very many Haskell packages that do all kinds of magic with CPP depending e.g. on compiler version. - Einar Karttunen