
Hello,
On Wed, Jun 24, 2009 at 3:47 AM, Simon Marlow
On 22/06/2009 00:21, Conal Elliott wrote:
Amen to Iavor's proposal! ...
On the other hand, having module names be independent of package names means that
Just to be clear, I was just proposing a _convention_ that we should use when it's applicable (which I think is in many cases) and not a policy of any sort. In particular, if two different packages are providing the exact same functionality, then it may make sense for them to provide the same modules.
- we can have multiple packages that implement the same API, making it easy to compile code against different implementations of an API
- we can reorganise the contents of package without requiring any changes to source code, only .cabal files
I agree that both of these are desirable in some situations (and they don't conflict with what I was proposing). In my experience, being able to replace one library with another without having to change the code is the exception rather then the norm, mostly because the whole point of using one library over another is that they are different somehow (licensing issues provide an exception to this rule, but I don't think that's the norm). For example, I might change my library to depend on the uu-parsing combinators rather then parsec. Both provide similar functionality, but I still need to change the code more then simply adjusting the imports.
A package conflates lots of things - perhaps too many things. But one thing a package is useful for is to behave like an interface; a package is an API. I've been thinking that we should make it easier to construct packages that are nothing but views on other packages, i.e. a pure interface. Right now it's possible to do this (this is how we implement base3-compat), but it's not convenient.
A view has the advantage that it can hide parts of the packages it depends on, and can hence change less frequently. So by depending on a view you get a more robust dependency. We're considering doing something like this for the base package in GHC: base-internals would be what we currently call the base package, and "base" would be a view on that that hides the GHC.* modules, and hence doesn't change its API as often. (there are various options here, I think Ian is going to outline the proposals soon).
I think of a package as convenient way to distribute a collection of modules that do something. As such, a package is likely to _have_ an API but I would not say that it _is_ an API. I think that the idea of "interface" packages is also useful and interesting, but I don't think that all packages need to be like that. For example, if we were to identify some kind of "standard" API for parser combinator libraries, then we could have packages that provided implementations of this API for different parsing libraries (e.g., parsec-common-api, uu-common-api, readp-common-api etc), these packages would mostly do renaming and small fixes to make the implementations match the interface. Then, it would be up to a programmer to decide if they want to write their code against the common API (to gain portability) or to use a specific library (because it provides some nifty feature). As Wolfram wrote, at the moment we have no (machine checked) way to provide an interface without an actual implementation but we should keep this distinction in mind when we design libraries. -Iavor