Update: After a lot of discussion with fellow Lispers, and comments that followed the posting of this article to Reddit, I have decided to reverse my decision of moving to Racket. Common Lisp is a beautiful language to work with, and even beauty has flaws. Below is the unaltered article.
In a previous article, I had mentioned how I was looking for another programming language to learn. This is a follow-up to that article – it will explain things such as why I am moving, where to, and what will happen to my existing code.
Common Lisp has been my language of choice for just about a decade of exclusive use – I haven't used any other language since migrating from Python in January 2008, aside from studying some newer languages such as Racket, Julia, and Kotlin, but no actual usage. Common Lisp has introduced me to what being a real programmer is all about. It has changed the way I write code. It has even changed the way I think. Frighteningly, it has even found its way into my subconscious in the form of strange dreams about parentheses, and even bugs I have attempted to solve for days have had obvious solutions presented to me in dreams. In short, Common Lisp is a big part of my life, and it always will be – it has defined who I am for a long time, and that will never change.
That being said, there are numerous areas where I think Common Lisp could improve.
Zach Beane has done an excellent job with Quicklisp, and it is far better than what we previously had available, but still has a few problems. Zach puts a lot of effort into curating a list of compatible software together into the form of a "Quicklisp dist" rolled out approximately every month. While this is great and puts near-zero maintenance on developers, it poses a few problems.
Firstly, Zach is a single point of failure. Yes, anyone can maintain their very own Quicklisp dist, but it isn't going to see the masses, and the Quicklisp internals are not very well understood by anyone other than Zach.
Also the fact that the official dists are rolled out so far apart (a month or longer in the software world is an eternity), means developers cannot push hot-fixes or address user-reported bugs in a timely manner, without pushing maintenance onto the users by having them checkout upstream sources.
Modern languages such as Julia and Racket offer central repositories where a developer can register their software projects, and will be automatically indexed periodically, so that users can continue to install and update software without any maintenance, and still receive updates quickly when needed. Additionally, they push managing version dependencies onto the developer, which I do not believe to be a bad thing. In constrast, Common Lisp libraries are rarely versioned, and all of that maintenance is forced upon the Quicklisp dist curator.
Common Lisp libraries are rarely ever documented. "Docstrings" and code comments are not user documentation. A successful project to be received by the public needs to have real offline user documentation, complete with plentiful usage examples, tutorials, imagery, and anything else that will transition a user more easily. This does not really need much explaining – Common Lisp software is mainly targeted at other developers that aren't afraid to read code and modify it to their liking.
One of my favorite things about Racket, is its documentation, and the tools such as Scribble that it provides for writing documentation. Nearly all Racket software has excellent "offline" documentation. I can only count the number of Common Lisp projects that I've seen have actual documentation on one hand - and none of them are presented as well as Racket's.
Additionally, the CLHS (Common Lisp HyperSpec) is very rough on even seasoned Lispers. It is very difficult to write portable Common Lisp, when much of the standard states something is undefined behavior or implementation-dependent, and sometimes the answer you are looking for is mentioned in a not-so-obvious section that is difficult to locate or parse.
Common Lisp software is of usually very high quality – if you take into consideration that it was more than likely developed by a single person and then stopped being maintained shortly thereafter. Common Lisp programmers are usually exceptional thinkers and writers of code, but they are just one person – they cannot think of every edge case, find every major bug, write documentation, or keep interest over other priorities for very long.
This hints at a very real problem with Common Lisp: it has a tendency to attract people that employ the 'NIH syndrome' and refuse to collaborate. There is a large overlap of software available, and there is a large selection of low-hanging fruit for new developers. This coupled with the fact that the language is small, relatively speaking, hurts the language immensely.
Simply put, Common Lisp is stuck in the past. Having a real ANSI standard that isn't likely to change any time soon, means other languages blaze on past the Greenspun rule. It also means antiquated symbols such as
GENTEMP or the
*-IF-NOT symbols are here to stay and confuse newcomers. Not only is the standard stuck, but users are stuck good on their dated ways.
On the flip side, having a real ANSI standard is also a very good thing – but it shouldn't stop the community from amending it with modern features such as standard threading and Unicode support, or system definitions.
There are numerous other issues I have with Common Lisp too, but I tried to stay out of language details and more about overall issues that surround the language and ecosystem that have bothered me for quite some time. Additionally, I do not want to sound like I am completely against Common Lisp – I love the language despite its many flaws.
I will continue to use it indefinitely, though some newer projects of mine may use another language. I have built up a very nice collection of libraries related to graphics programming, linear algebra, and game development in Common Lisp, and as these areas are of particular interest to me, I just don't see it wise to re-implement my life's work, probably poorly until I really get to know that language. For that reason, I will continue to work on those libraries, and projects of that nature, in Common Lisp.
After 8 months of considering a handful of languages, Racket is where I will be moving to. I read the complete guide twice, and there is not much I do not like about the language design. I will not be listing numerous reasons why I like this language, as there are far too many, and I would just be repeating what Fare has said. Additionally, I get to stay where I am comfortable – nestled between two parentheses.