First a small detour

I program in Objective-C and Swift daily, because those are the languages that Apple requires developers to use to build software for their platform. It’s not a strict requirement to use any of these two languages if you go cross-platform, but for good integration you would eventually have to write platform code in them.

After using Swift for more than 5 years I can confidently say that it’s getting worse with each addition, very similar to how C++ ended up being the monster it is. In comparison, Objective-C is simpler, somewhat minimalistic, and yet it did a great job for many Mac developers for a long time. I’ve heard that Swift code leads to less crashes and better performance, but that’s not what I’ve experienced. Well written Objective-C code can be easy to understand as much as well written Swift code. But overly complex Swift code is much more difficult to maintain and understand than similar Objective-C code.

What does Common Lisp have to do with any of this?

I started developing in Common Lisp around 12 years ago and was always fascinated by it. The developer experience, for such an old language with old tools (Emacs + Slime for example), compared to Visual Studio Code and a modern language is still unmatched. You really have to get into it for a few months of writing code, debugging and inspecting to understand the full power of the environment. It feels like you are evolving a living organism, adding ADN to it, watching it take shape while it’s going around doing stuff, inspecting its internals. It is a fun, fulfilling and liberating experience.

Often developers say how you can make a mess of a Common Lisp codebase because of such freedom it provides. But isn’t that the same with any language? The world is full of horrible, inscrutable messes made in C++, Java, Swift and Rust. Any language in the hands of the wrong developer will provide enough (or not enough) power to create such messes. What Common Lisp gives you is great abstraction tools to build software in the simplest way, without having to create odd contortions to fit a type system and satisfy the compiler.

I can probably hear the rustacean over there saying how a properly constructed Rust program, once it compiles will work without bugs, to which I’ll laugh loudly thinking of all the bugs that I had to fix in statically typed languages that were not caught by the compiler. The reality is that you need unit tests anyway, for any program written in any language.

But the easy with which you can inspect a running Common Lisp program to see what’s wrong with it, by calling functions on the REPL, makes for a faster interaction than compiling in an IDE, running the program and setting a breakpoint where the stuff you intend to debug is being called. It cannot be overestimated how much this helps in building stuff faster.

Does any of this really matter?

Any day to day programming job can be difficult, challenging and also boring. Common Lisp, at least, takes the boring out of it. I really don’t understand how Go developers can build software without feeling soulless with such a dumb language. There are practicalities built into the language for sure, but overall it feels very bland. One consequence of it being such an easy and simple language is that it gathered a strong community and lots of libraries. It was designed so you can toss N amount of developers + Go and software comes at the other end.

But for the love of God (the one you prefer), it makes programming such a repetitive task. How long before Copilot is able to write all the code any Go developer now writes by hand?

Perhaps this rant is because I see programming as a creative activity, such as writing a novel, more than as an engineering discipline. That doesn’t mean that I don’t write unit tests, documentation or use CI.

So every single day, after work, I reach out to Common Lisp for writing my personal project (next business). It feels like I have superpowers, as if I’m understood by some very old wise man that’s there for me when I shape my program. It also helps that the language specification is set in stone and won’t change at the whim of the community. Just take a look, as an example, at that list. Never ending changes that will make your code constantly obsolete. The same is happening with C++, except modern C++ changes are probably welcome by most codebases. But still, there’s a ton of crap added to every version of the standard library. More gotchas to be aware of, more UBs.

Life is limited to keep thinking about ever changing stuff. Language designers making the same mistakes other designers made in the past, and the community always pressuring for more bells and whistles (If you are into PL design, watch this video), more syntatic sugar, exerting its power over original designers of the languages. So turning to Common Lisp is always a breath of fresh air, and that’s why my next project is being built with it.