Common Lisp is one of those languages that you either love or hate (for any definition). Unfortunately, the later group is rather quite large and the reasons for that dislike go from the simple parenthesis (I still wonder what these little fellas did to annoy so many people) to many other things. One of them is usually known as the library problem.
The library problem can be seen from many different angles: lack of libraries, lack of decent libraries (and really good libraries), easy of install, easy of use, the central repository, the batteries included, etc, etc, etc. I guess if you want, you can always find an argument to complaint about libraries. It really doesn’t take too much effort. And for the past few years, this library problem has been one of the main arguments against the use of Common Lisp by non-lisp programmers. Even by those ones who don’t use the parenthesis argument to dislike Lisp.
There is some truth in this library problem of course. The state is not pretty when compared to other languages. However, it might be not that bad as sometimes is painted but it’s there. The elephant is in the room! However, if you never experienced a library problem in any other language I guess you belong, give it or take it, to two main groups: you use a very specific set of libraries that happen to be very good in that language/environment/etc, or you really don’t use libraries a lot. In the end, I believe it always depends on what you actually need/use or want (e.g., the batteries included). Sometimes you have excellent libraries in language foo but not the equivalent in language bar (e.g., is there a numpy+matplotlib equivalent in Ruby?). And just because everything was done twice in Java, it doesn’t mean they are that great (“Been there, suffered that”). And finally, do you really need to invent a new language just because of this issue? Well, maybe yes, maybe not…
Although I’ve been programming in Common Lisp for quite some time (for the record, I am not a Jedi Lisp Knight), I never felt the need, or was forced, to use so many libraries like others do. Mainly because of the stuff where I use Lisp. But from time to time, you really need a library because you want that one functionality or simply because you wish to try/play with something. When the library you need is self-contained or with a very small dependency number, the library problem is essentially a non-problem. Ok, sort of. At least the installing/using side of the coin. The quality side is a complete different story. But when you require something more complex, things can get tricky. Really tricky. And you might feel tempted to join the dark side and start believing Common Lisp has a real library problem… which is not what you want.
What you want is a simple and easy way to look for libraries, install, update when necessary and, more important, just use them! So far, systems like, for example, clbuild, start nice but then something happens and your environment becomes messy. It can be just my own fault but it happens. And the manual way is a nightmare. In short, most of the time you worry about what to install, how to install, how to keep the system tight and clean, etc, etc. At some point, you start choosing your libraries by the number and type of dependencies they have. Which I am not fully sure if this is a good thing. And what happens when you really want to try a really cool library but it has a complicated library dependency structure? If you have time to spare, you will likely get lots of worries (and this is assuming you will be successful at the end). Otherwise, you will be frustrated for not trying it.
So, how do you solve this library problem? With Quicklisp. Unless you were recently living on the other side of the Lisp universe, Quicklisp is a system designed and implemented by Zach Beane which “aims to make it easy to get started with a rich set of community-developed Common Lisp libraries”. At first sight, it might look as just yet another attempt to solve the Common Lisp library problem, where so many failed and few had some mild success. Although it is in an early development stage and is not widely available/distributed, Zach is distributing it to anyone who wishes to try it. And I am glad I decided to give it a go.
Quicklisp is really what you always wished it existed for installing and managing Common Lisp libraries. You can see some of the details in the screencast but the quick version of Quicklisp’s advantages are: 1) easy to setup (you just need to load a single file, regardless of your lisp implementation); 2) to install a library is just typing one command and, 3) all the dependencies are taken care of. All the other operations are also very simple to execute. No more worries about how to install a library and dependencies. After a while, you even start installing things just for the fun of it! Yes, It’s really that simple.
I feel there will be a time for Common Lisp programmers: before and after Quicklisp. To be honest, I really hope Quicklisp gathers the momentum and adoption in the community. Even now I’ ve just read in the SBCL developers mailing list the proposal to include Quicklisp in SBCL when it’s properly released. Yes, the “half-baked, incomplete, unmaintained and tasteless” libraries problem will not be solved but at least will be “easy to install them” (in Zach’s own words). There is still a lot to be done but I am confident. And finally, we can all stop worrying in how to install a Common Lisp library (or some of them) and use our time to actually do some coding. And may the Force, I mean, Quicklisp be with you! :-)
2 thoughts on “Quicklisp or: How I learned to stop worrying and love installing Common Lisp libraries”
I think that parenthesis-hate is the result of not learning proper lisp code formatting, not using an editor that automatically formats code for lisp, and not depending on the editor to show parentheses matches. Proper tools make parentheses unproblematic. I feel that those with affection for lisp need to emphasize these points more often. (Counting parentheses can become second nature, too–just like counting digits in file sizes to determine KB vs. MB vs. GB–but saying so won’t win anyone over.)
I turned quicklisp into a gemfile-like thing with a very simple macro inside my .asd files. Here’s an example. I list the packages that I need installed and loaded for this application in *asdf-packages*. The (ql:quickload) loop makes sure that they are installed, updated and loaded. And the ,(eval depends-on) in the macro lets me feed the *asdf-packages* list into the defsystem.
(defmacro do-defsystem (&key name version maintainer author description long-description depends-on components)
:depends-on ,(eval depends-on)
(defparameter *asdf-packages* ‘(net-telent-date cl-ppcre uffi hunchentoot cl-log ironclad cl-json drakma trivial-ldap))
(loop for pkg in *asdf-packages* do
(ql:quickload (symbol-name pkg)))
(do-defsystem :name “ldapadmin”
:maintainer “Carlos Konstanski ”
:author “Carlos Konstanski ”
:long-description “ldapadmin is an app of some sort.”