a poorly thought out suggestion for cabal and packages that have lots of instances

Hello, There are a number of libraries like syb-with-class, happstack-data, etc, which provide a new class that potentially has a lot of new instances. For example, let's say I want a 'Data ctx Text' instance. Where should that go? To avoid orphan instances it would need to go in the 'text' package where Text is defined. But it seems unlikely that I am going to convince the authors of text to add additional dependencies on things like syb-with-class, happstack-data, etc, just to satisfy a small number of users. A second place to put the instance would be in the syb-with-class package. They will be orphan instances, but as long as you can't import the Data class without also getting those instances, it doesn't seem like much could go wrong. But now syb-with-class has to depend on all the libraries that it is going to provide instances for. So, I have just shifted the problem from one library to another. A third option is to just define the instance in the library where I want to use it. But now I have opened up the possibility of conflicting orphan instances for the type -- which is no good. A fourth option is to create a new package which contains just the instance. For example: syb-with-class-text This still opens the possibility of conflicting orphan instances. But at least there is a version that is supposedly the 'official' one. The problem is that it seems like this might really clutter up hackage? Also, it is annoying to have to create and maintain and entire new cabal package just for one single class instance. And if i want to install all the instances, it would be annoying to have to do 20 different cabal installs. What might be nicer is if I could have a single project directory that somehow generated all those instances. And if cabal new how to work with them as a family. Something like: cabal upload syb-with-class* cabal install syb-with-class* Obviously, I have not really thought this through all the way. I just know that I am continually wondering what I should do when I want to do something like add a Text instance for syb-with-class? If we were to get really experimental I might suggest that when you install syb-with-class, you don't automatically get all the extra instances by default. But the package system and compiler would know they exist. So if you tried to write code that required the missing instance, it would suggest that you need to install the extra package. This would help reduce instances of people accidentally creating a conflicting instance. But I am sure it makes something else horrible happen instead ;) - jeremy

Hi Jeremy
A fourth option is to create a new package which contains just the instance. For example:
syb-with-class-text I may be mistaken - but can't you just put the instance in a module (within syb-with-class) and make syb-with-class not import it by default?
Why do you have to create a new package? Is there something I've missed? Marc Weber

On 16 March 2010 11:50, Marc Weber
I may be mistaken - but can't you just put the instance in a module (within syb-with-class) and make syb-with-class not import it by default?
That would still require syb-with-class to depend upon Text, etc., which is probably not a good thing to do. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

Excerpts from Ivan Miljenovic's message of Tue Mar 16 01:53:13 +0100 2010:
On 16 March 2010 11:50, Marc Weber
wrote: I may be mistaken - but can't you just put the instance in a module (within syb-with-class) and make syb-with-class not import it by default?
That would still require syb-with-class to depend upon Text, etc., which is probably not a good thing to do. Doh. I've missed it.
Sure. I think MissingH has similar trouble: You only want to use one or two features - but you have to install all dependencies. Three choices: a) add dependencies to syb-with-class. You could even think about refactoring text and split it into text-types and text-implementation. This way adding a dependency isn't such a big change. But it still is bad because syb-with-class maintainers in general don't want to align their changes with text updates. Neither do they want to fix problems arising from changes in all those packages it should provide instances for. Usually maintainers ask for splitting off such code. (vim backend for Scion is one case ..) On the other hand the Firebug people chose to align releases of core Firebug plugins to enhance stability and user experience. Anyway this is what some packages do. Eg Vim *does* contain many gui backends. You can't download a vim-common shared library and install vim-gui-gtk vim-gui-... There would be too many combinations. Package maintainers have stripped them down to vim-tiny vim-gui-with-X-huge-features ... or similar. But it's easy in this case - no (?) application depends on Vim. b) using conditional compilation usually package writers writing package descriptions for distributions such as gentoo, Debian just compile all backends. I think Debian always enables both: gnome and kde. Adding use flags to gentoo for each feature would be overkill. So in the end this is equal to a) (IMHO) I can not even estimate the amount of work it requires to make packaging tools cope with conditional compilation. You have to start propagating features to base packages etc. I think ivy claims to solve this kind of issue partially. (I don't know it that well) c) add many additional packages
The problem is that it seems like this might really clutter up hackage? The way to go is improving tools (Hackage, IDEs, cabal-install) to cope with this situation.
I'd even propose renaming the extra package to syb-with-class-text-instances. Then everybody can see what it contains. tools such as cabal-install will have more trouble to find a solution because there are much more possible solutions to take into account. One way to cope with this is always use latest version and fix broken packages.. Last but not least it is also a marketing issue: Eg OpenERP vs Adempiere: OpenERP is said to have *many* plugins. But some of them just add some DB fields or make a field have more characters. Adempiere contributors tend to call this a "localization" of their software. (You can read this up on their sf forums :) ) But I don't think anybody really cares whether we have 3000 or 5000 packages on hackage. In the end we all care about getting things done. Installing 20 packages and running cabal 20 times more often does matter. So what is correct? I don't know. Marc Weber

Hi Jeremy Is this really a problem practically rather than hypothetically? Data.Text and Syb-with-class - both are general, neither uses the other for their implementation, adding a dependency to one sounds like a bad idea - so making a separate 'instance' package seems most sensible. Unless you believe otherwise, Data.Text appears more 'general' than happstack-data, so Data.Text shouldn't provide happstack-data instances. Then its a choice between adding a direct dependency on Data.Text to happstack-data and defining the instance there or making a separate instance package again. A category on Hackage for 'instance' packages would seem to make sense as would a naming convention for the packages, hopefully stopping any proliferation of identical packages. Best wishes Stephen
participants (4)
-
Ivan Miljenovic
-
Jeremy Shaw
-
Marc Weber
-
Stephen Tetley