
On Mon, 2009-08-24 at 09:59 +0200, Johan Tibell wrote:
6) Integrate with the rest of hackage. This means instance of PrettyClass, Parsec, and Binary. I noticed a number of parsing utilities for IP addresses - lots of duplicated effort here.
I must disagree here. We don't want hard coupling to lots of other libraries. i.e. we don't need convenience functions like:
get :: Socket -> Binary a
These ends are better reach by the client writing the glue code. It's easy to get a combinatorial explosion in the number of functions if we try to provide an integration point for each library out there.
Yes, I think this is a trap that we often fall into, that we think we make libraries better by providing exactly the one function that people need, in some kind of "high level" "all in one" operation. As an example, I'm going to pick on Don because I know he can take it ;-). The download package provides: openURI :: String -> IO (Either String ByteString) which is great, but also these: openAsTags :: String -> IO (Either String [Tag]) openAsXML :: String -> IO (Either String [Content]) openAsFeed :: String -> IO (Either String Feed) which are all instances of (roughly) this pattern: openAsFoo = Foo.parseFoo `fmap` openURI The point is: *** don't fear the composition!! *** Let the user / caller do the composition. The API is simpler and easier to understand if the user does the composition rather than providing every use case. Also the package dependencies are much simpler. Sure, point out in the docs that the user could use it that way with other libs but don't provide every composition in the name of convenience. A Microsoft blogger has a nice short (and rather sarky) article on this topic: "Programming means that sometimes you have to snap two blocks together" http://blogs.msdn.com/oldnewthing/archive/2009/08/04/9856634.aspx Duncan