One fine hackathon with Common Lisp

Last month I went to a Hackathon organized by Hubbel, a local club for programmers of all skill levels. The theme was simply “make something cool”, and to achieve that mythical coolness I picked Common Lisp.

The concept of a hackathon can be a lot of different things. Oftentimes these things end up being very competitive, with little sleep, discussing in circles, pivoting, discussing some more with mentors, grabbing some food, and hammering away on your keyboards before a haphazard presentation in front a discerning panel of judges, and equally exhausted rivals.

Hubbel’s hackathon was nothing like that. Thankfully.

“Make something cool” was this hackathon’s theme. People were free to group up, or not. People could stay at the venue, or not. Participate the whole weekend, or just for a part of it. No requirements to complete your project even. As a developer nearing my forties, I long for playful exploration, not cutthroat competition.

Why Common Lisp? #

Common Lisp (CL) is a programming language that was standardized in 1994 (!). In the 70s and 80s there were a lot of LISP-based languages, where language divergence hindered interoperability and caused a lot of duplicated work. By standardizing one hoped to take the best features from many of the prevailing LISP languages, and build a strong, evolved LISP programming language. Work on CL first began in 1981, and continued all the way to 1994, with the publication the third and final version of the CL standard. In the years since, people have kept, and keep picking up CL and becoming fascinated by it. CL certainly has its warts, but it has several strong and interesting ideas. For more enthralling LISP-history check out Let’s LISP like it’s 1959.

Person sitting in front of a laptop. Behind there's an alien holding a flag with the title 'LISP'. On top of the alien there's a small chicken.

Here’s a person I drew hacking on lisp, and standing behind is the unofficial lisp mascot. It’s alien tech!

Building that cool CL thing #

Though fascinated by CL, I haven’t built sizable applications with it. So, to set the bar sufficiently chill 🍹, I picked a web app tutorial using CL.

I love that the whole hackathon was judgement-free. For the whole weekend, no one turnt their nose up when I said I was doing a CL tutorial for my cool project.

I didn’t get that far with the tutorial, but I learnt a lot. And laughed a lot with the fellow developers who were working on their projects around me.

Some of my results from the tutorial work:

  • 💪 Got more comfortable using Emacs + SLIME for CL-development.

  • 🕳️🐰 Fell into a rabbit hole around package management. The tutorial recommend using Quicklisp for downloading dependencies, but Quicklisp doesn’t use https. So then I started surveying alternatives such as QLOT, OCICL and CLPM. Finally, after some false starts I ended up using Guix to grab the dependencies I needed.

  • 🔍 The next challenge was to make my CL code actually find the downloaded CL-packages. In the CL world there are several implementations (engines) built to run CL programs. I picked SBCL as the implementation for running my code. Though all CL implementations mostly conform to the standard, the standard itself has a few blind spots where implementations may diverge. To paper over these differences there’s ASDF for expressing a system, which is the CL term for a program. After reading about how ASDF locates systems I learned where I could add a symlink to let ASDF locate Guix’s CL packages, like so: ln -s ~/.local/share/common-lisp ~/.guix-profile/share/common-lisp

  • 🏋️ The tutorial recommends calling load to load the .asd file which defines the project. But for that to work SBCL needs to be running in the correct working directory, or else the load command won’t find the source files to load. Call (uiop:getcwd) in the Slime REPL to learn the current working directory. UIOP is part of ASDF, and provides many useful IO utilities. Use (uiop:directory-files "./") to list files in the current working directory. To change current working directory with SLIME you can call slime-set-default-directory. Afterwards you should be able to load the file, but you might get an error still from missing ASDF package.

  • 🔌 ASDF isn’t automatically loaded by SBCL. So calls like (load "cool-system.asd") will fail on missing package. To solve this you must first load ASDF by calling (require :asdf) in the REPL. A require call loads a system, unless it has already been loaded. To ensure that ASDF is alway present in the SBCL REPL, you can create an SBCL user initialization file at $home/.sbclrc, and put a call to require the asdf package within.

Are you still with me? At this point we’re ready to start completing the tutorial in earnest. Haha. Yes, this can definitely be a tricky onboarding experience for new developers.

I’m making a mental note to see if I can improve the tutorial itself so that it gives some thorough guidance on how to get your lisp code properly loaded. Update: Upon revisiting the guide, I saw that it states that you should follow a separate guide on how to configure the CL environment. Gah!

After getting my packages loaded, I quickly progressed in the tutorial and got to a point where I had a web server running and serving up html.

Time-wise I think I spent 40% nerding out with new acquaintances, 40% tinkering with package loading, and 20% working on the web app itself. I learnt and laughed a lot, so I’m marking that as a success in my book.