Saturday, January 5, 2008

Common lisp libraries - victims of drive by programming

In order to make an apple pie from scratch, you must first create the universe - Carl Sagan.

Recently I wanted to cook some embeded prolog, but modularly designed on top of some current lisp pattern matching library and add some tests.
So in the last few days I went shopping for regression test & pattern matching libraries. Among the illusion of abundance I encountered the known plague among the lisp(*) world, hackbraries (**).


Let me tell you first my criterias as different people have different expectations and mine are as fallows:
1. Work out of box
2. Portable across major implementations and OS(s)
3. Documentation with examples
4. Regression tests
5. asdf packaged

1st Whenever I choose using somebody's else code I expect to work out of the box.
If domain covered in the library was interesthing to me I would code it myself.
The reason to use somebody's else code is because I don't give damn about the implementation, I just want my problem solved.

2.
I regularly work with Allegro & LW under Windows and Allegro & SBCL under linux, and I expect the library to work on all of them out of the box. If I had a Mac I would test with Mac and OpenMCL too. The correlation between portability and library quality is very strong.
Sticking to one implementation and OS is understandable if you're a vendor that want's to implement super performing library using implementation specific features, but if you're in the open source world keep in mind that number of lispers is relatively small, and after you divide them with major implementation / OS combinations the numbers would be far smaller.You might be the only one that could use it.
So stay away from implementation specific extensions as long as you can.

3. Documentation matters to help people understand what the library is actually doing and how is doing it. You are coding in different standard in a domain that I probably don't understand. Put some documentation so I could learn what do you achieved in your library , what's missing and how to use it.Also documentation offers another perspective why you wrote the code such that.

4. Tests are something that I run first when they exist, and they are good sign of library quality. Tests make sure that library works at least as author expected it to work. Also tests make a great learning material how to use the library. I learned more from hunchentoot and weblocks tests than from all documentation, examples and articles togather.

5. ASDF is de facto standard in the open source world, almost all the high quailty and popular libraries have it so fellow lispers expect it. Why bringing a disappointment for only a minute fo work.

So why does most of lisp libraries fail the above criterias while there is a relative sea of abundance?
I think it's partially because of nature of lisp and it's users. Lisp is a great language for rapid prototyping so if you need something, you could hack it yourself quickly, for an excellent example check this
link , it shows how
Tamas asked for a unit testing library and Frank Buss wrote one in 10 lines.
When all the functionality is only 10 lines, documentation,tests and asdf file doesn't make sense. As more functionality is needed, the code grows bigger untill our 10 liner expands to dozen of files and hundreds lines of code
thus becoming a *library*. If it's lucky it'll get an asdf file because that's easiest to add . The author and folks that use it from the beginning know it by hart so they don't need documentation nor tests. The *library* founds it's place in common-lisp.net or sourceforge, and gets bugfixed for a while untill all the author(s)/*maintaineer* got hit by truck or lose interest. Lisp PR advertise it as a possibility, though most of them didn't even tried it. And everything is fine untill some outsider actually want to use this *library* for real. Soon enough he will found that it's easier for him to hack some 10-liner by himself instead of digging through somebody's else code. After more functionality is needed, the code grows bigger untill our 10 liner expands to dozen of files and hundreds lines of code thus becoming a *library*.
..
The vicious circle starts once again.

Lisp is like a pulley that will enable you to make code quicker than in any other language I tried, but you still you have to work hard to produce something than could be consumed by other. There are many high quality lisp libraries that are fine examples how things should be done the right way, but there are also ocean of halfbaked bundles of code that only waste your time.

If it ain't broke, maintain it

cheers
Slobodan

(*) When I say lisp I mean common lisp, for other uses I use lisp family of languages
(**) Hackbrary- Overgrown bundle of code lacking documentation, unit tests and maintenance, usually broken, posing as library.

5 comments:

  1. This is interesting and I think I agree... as long as *you* give *me* some credit :) There is one "pattern matching" library that meets all the requirements you list :). Moreover, I did exactly what you suggest in the past: I maintained semi-orphaned pieces of software. Maybe it wasn't the trt, maybe it was.

    Cheers

    Marco

    ReplyDelete
  2. Cl-unification has one of the best documentations I've seen.The code is clear, portable and examples are good.
    The only things it lacks are tests.
    Everything else is up to the users.

    ReplyDelete
  3. Tests depend on a test suite. I use Franz tester.cl suite, but I do not want to impose it on the users. Moreover, as usual, time is limited.

    ReplyDelete
  4. If you have tests please post them, even if they are unportable.
    It's usually easy to convert them into some portable library as rt.
    Also It makes people learn what you had in mind when writing the lib. Tests are powerful learning tool.

    ReplyDelete
  5. Hi

    The new CVS of CL-UNIFICATION (as of July 2008) has the 'test' subdirectory in. You can see which tests are listed.

    Cheers
    Marco

    ReplyDelete

Note: Only a member of this blog may post a comment.