Update: Be sure to also see the post The Perils of Lisp in Production, a complementary post.
I believed, and many others as well, that while Lisp is a flexible and expressive language, it would not be good in production environments. The principle reason I believed this was that Lisp is far too flexible and far too powerful to be simultaneously worked on by a team or several teams of people. With everyone creating their own macros and everyone writing code in their own style (perhaps some in an imperative style, or — in my case — largely functional style), how could everyone possibly understand code or be on the same page? The semantics and flow of the code would just not be uniform enough.
Well, it turns out, this preconception of Lisp in “production environments” is wrong.
I recently moved to Colorado (hence the stagnating blog) for a job. To my luck, it is a job which exclusively uses Common Lisp. The code base is several hundred thousand lines, which is a lot of Lisp.
My first semi-long-term project was to replace the system which generates printer commands to format and print fingerprint cards. This included a way to specify fingerprint cards which could be interpreted by the system and pull the necessary “fingerprintee” information out of the main database, format the card, fill it out, and send it to the printer.
I was luckily able to essentially begin this project from scratch, as the current code in there was not sufficient and abstract enough to deal with all of the possible cards.
However, while I did this project, I had to jump in and do tangentially related things with the code base. Anything from minor fixes to changing how the entire build process works.
Did I find myself gimped by the fact it was all written in Lisp — and that many of the developers who worked on the code no longer were a part of the company?
The code isn’t necessarily trivial, as there is some macro-generating-macros about, some reader macros, etc. None of which could be delightfully explained by the author who no longer exists. But was it harder to understand than, say, Java? No.
The big difference between working on production code in Lisp over Java is that because Lisp doesn’t impose some rigid language structure, you can’t just mindlessly be a code monkey and wield the refactoring excavator (usually cut-and-paste in Java’s case) in the same way. Doing that will likely lead to unintended consequences. Dare I say that sometimes you have to think when you refactor or change code in Lisp. Is this a bad thing? Perhaps. Until you realize Lisp’s refactoring excavator is a lot more powerful than cut-and-paste. The entire language itself is a refactoring machine. Often times fixing code is as easy as writing a simple macro to just remold the code into the way it should be. If a macro would be too hacky, then #+#:ignore will comment out the entire S-expression ahead where you can test a replacement.
One especially nice thing about learning a new code base in Lisp is that you don’t really need any special tools to help you out. Emacs and SLIME help, but there are built-in features — built-in features located in the ANSI Common Lisp language standard — that help you out. Anything from inspect to describe to documentation. Class introspection at the REPL is a breeze, as is object introspection. If you have the privilege of using SLIME, then looking up definitions of symbols is priceless.
All in all, I think the idea that Lisp is a terrible language in production environments is absolute rubbish. With this new acquired experience, I think quite the opposite. I think Lisp is actually much better than other languages in production environments because of its flexibility. That is unless you want mindless monkeys writing your software.