It is somewhat of a surprise to me that I'm making this post, given that there was a day when I thought Haskell was moving too slow ;-)

My problem here is that it has become rather difficult to write software in Haskell that will still work with newer compiler and library versions in future years. I have Python code of fairly significant complexity that only rarely requires any change due to language or library changes. This is not so with Haskel.

Here is a prime example. (Name hidden because my point here isn't to single out one person.) This is a patch to old-locale:

Wed Sep 24 14:37:55 CDT 2008  xx...@xxxxx.xxxx
  * Adding 'T' to conform better to standard
  This is based on information found at

http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations
diff -rN -u old-old-locale/System/Locale.hs new-old-locale/System/Locale.hs
--- old-old-locale/System/Locale.hs     2010-04-23 13:21:31.381619614 -0500
+++ new-old-locale/System/Locale.hs     2010-04-23 13:21:31.381619614 -0500
@@ -79,7 +79,7 @@
 iso8601DateFormat mTimeFmt =
     "%Y-%m-%d" ++ case mTimeFmt of
              Nothing  -> ""
-             Just fmt -> ' ' : fmt
+             Just fmt -> 'T' : fmt

A one-character change. Harmless? No. It entirely changes what the function does. Virtually any existing user of that function will be entirely broken. Of particular note, it caused significant breakage in the date/time handling functions in HDBC.

Now, one might argue that the function was incorrectly specified to begin with. But a change like this demands a new function; the original one ought to be commented with the situation.

My second example was the addition of instances to time. This broke code where the omitted instances were defined locally. Worse, the version number was not bumped in a significant way to permit testing for the condition, and thus conditional compilation, via cabal. See http://bit.ly/cBDj3Q for more on that one.

I could also cite the habit of Hackage to routinely get more and more pedantic, rejecting packages that uploaded fine previously; renaming the old exception model to OldException instead of introducing the new one with a different name (thus breaking much exception-using code), etc.

My point is not that innovation in this community is bad. Innovation is absolutely good, and I don't seek to slow it down.

But rather, my point is that stability has value too. If I can't take Haskell code written as little as 3 years ago and compile it on today's platform without errors, we have a problem. And there is a significant chunk of code that I work with that indeed wouldn't work in this way.

I don't have a magic bullet to suggest here. But I would first say that this is a plea for people that commit to core libraries to please bear in mind the implications of what you're doing. If you change a time format string, you're going to break code. If you introduce new instances, you're going to break code. These are not changes that should be made lightly, and if they must be made (I'd say there's a stronger case for the time instances than the s/ /T/ change), then the version number must be bumped significantly enough to be Cabal-testable.

I say this with a few hats. One, we use Haskell in business. Some of these are very long-term systems, that are set up once and they do their task for years. Finding that code has become uncompilable here is undesirable.

Secondly, I'm a Haskell library developer myself. I try to maintain compatibility with GHC & platform versions dating back at least a few years with every release. Unfortunately, this has become nearly impossible due to the number of untestable API changes out there. That means that, despite my intent, I too am contributing to the problem.

Thoughts?

-- John
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to