Ever since publishing the Barium toolkit, I’ve been hinting at real applications waiting to be written. That is, non-trivial programs using Barium for their GUI. ChessLab is one such program, and the first to reach a standard of completion to be published.

Introducing ChessLab

ChessLab is a desktop application for chess players and chess enthusiasts.

It can help you:

  • browse through game collections and replay games;
  • keep a record of your own games;
  • maintain an opening repertoire;
  • evaluate and analyse positions;
  • play chess against the computer;
  • solve puzzles;
  • look at a (virtual) 3D chessboard.

ChessLab is written in Common Lisp and uses the Barium toolkit for its GUI. As such, it should run on any UNIX-like Free/Libre/Open Source operating system, including Linux and members of the BSD family.

ChessLab is released to the public under the terms of the GNU General Public License v3.

To give you a flavour of the program’s interface, here’s a view of the main ChessLab window:

And here is how ChessLab’s 3D board view might look:

If you are interested in ChessLab, please check out its webpage for further information, including instructions on getting it up and running on your computer. In the rest of this post I want to share some reflections on the process of developing a complex desktop application in Common Lisp, on top of the Barium toolkit.

A compact codebase!

First of all, let’s take a look at the program’s areas of functionality and the amount of code servicing them. At its initial public release, the complete ChessLab codebase is less than 4,800 lines of Lisp code (including empty lines, comments and everything).

Without relying on any dependency, this amount of code implements:

  • the complete rules of the game of chess;
  • a reader and writer for multi-game PGN files;
  • logic for converting between board squares and standard algebraic chess notation;
  • a chessboard widget with stateful event logic and support for various kinds of markings and graphics on top of the board itself;
  • a widget to typeset recursive algebraic chess notation (with wrapping and scrolling) and allow move selection;
  • a widget to display the game tree in a tabular format (useful for openings study), also allowing move selection (and, of course, scrolling);
  • a UCI interface to chess engines being run as an inferior process;
  • a separate dialog to configure chess engines for analysis and gameplay;
  • a parser and loader for Wavefront OBJ files to load 3D chess piece models;
  • a 3D board view using OpenGL for efficient array-based rendering;
  • an image cache for efficient handling of drawable images;
  • definition of all GUI structure, menus, event logic, handlers, error dialogs, etc.

Again, all this fits conveniently within less than 5 kLOC in total. If you have any kind of programming experience writing non-trivial applications, I’m sure you can appreciate the compactness of this codebase. In my experience using other languages, this code budget would be consumed by just a fraction of the GUI itself, or a few of the listed features.

Insane productivity!

When developing a complex application, Common Lisp is really a game changer! On several occasions I have gotten positively surprised by how easily I could get some feature done, and further, how bug-free and performant my initial code turned out to be. Even for experienced programmers (or perhaps, especially for them) Common Lisp has pleasant surprises in store.

Most of what became ChessLab was written in the span of a couple months here and there, by a single person who was simultaneously working on other projects such as Barium, and had a life outside of programming as well, such as actually playing some chess…

It is important to recognize the strongly non-linear effects of (smaller) codebase size and (higher) productivity on the feasibility of achieving a certain software product of a desired quality. Code cohesion is key: the less context and irrelevant details one has to juggle around, the quicker a program will emerge from the bits and pieces, half-formed ideas and visions lurking in the programmer’s mind, and will do so with fewer bugs.

At sufficiently high productivity there is no such thing as legacy code. Anything found in retrospect to be unclear or less than well designed can be thrown away and rewritten based on the latest insights into the problem domain. Another dimension here is communication between programmers; a team size of a single person is certainly an extremity, and a very efficient one (but one must acknowledge it has its limits and downsides elsewhere).

Owning the whole stack is really nice

Such claims of productivity might indeed seem insane to those who have never gained first-hand experience of how a powerful, interactive language can speed up development. This effect is further amplified by the use of the Barium toolkit, which I designed to be a simple, Lispy API for creating old-school desktop user interfaces. And it certainly helps that as the author of both codebases, I have a deep understanding of the whole stack, from the level of interacting with the X Window System to the domain of chess moves.

Let’s consider a practical example. How long did it take me to equip Barium with a missing binding to a Cairo function, when it became necessary? About 5 minutes, and I could test it right away without restarting the program. In a large company, experience suggests that such an obstacle, impossible to foresee and include in up-front planning, could easily take weeks to navigate, involving separate teams with disparate schedules and priorities, concurring product managers, several meetings and of course a healthy dose of politics!

In conclusion, I see ChessLab as an embodiment of the principle of building “On Lisp” (even though ChessLab does not go that wild with macros). I have personally felt the mighty productivity gains of bottom-up, interactive programming while owning the complete stack, free from any communications burden or bullshit tax project management overhead. As a programmer, this is clearly how I do my best work, and working in this mode is immensely enjoyable.

I believe the advantages could be preserved while carefully scaling things up to two or three people (but probably not further). Of course, it has to be exactly the right people, which is harder than any technical problem.

Other aspects

  • Performance: ChessLab loads a multi-game PGN containing more than 2,400 games in well under 10 seconds. The UI is snappy and does not consume significant CPU while running, apart from some redraw-intensive operations such as gradual resizing of the main window or inner panes. Very little performance tuning was necessary to achieve this; the few hotspots were quickly identified with cl-flamegraph and dealing with them was straightforward.

  • Portability: By virtue of being a Common Lisp application using Barium, ChessLab is usable (with unmodified source code) across the full range of systems I care about. In particular, it has been tested to work:
    • on x86-64 and arm64 machines;
    • on Linux and OpenBSD operating systems;
    • with SBCL and CCL Lisp implementations;
    • with X.org and XWayland desktops.

    It probably works elsewhere, too, but that is plenty for me.

  • Ease of deployment: Using Common Lisp facilities for saving a Lisp image, it is very easy to create a single ChessLab executable. Point-and-click people could even set it up as the default handler of *.pgn files.

Conclusion

In The Barium Experiment, I introduced the concept of long-term durable computing, and shared my plan of writing programs that would stay usable without a constant stream of maintenance updates in the face of dependency churn.

ChessLab is a good candidate for this experiment: the domain is well understood (let’s hope the Laws of Chess won’t change for another couple hundred years or so…) and the program’s foundations are bound to remain stable. ChessLab also served as a real-world testbed for the Barium toolkit, driving the development of several features and unearthing a couple performance issues.

As a flagship Barium application, I will make sure ChessLab gets ported to whatever breaking changes the toolkit might see in the future. I also plan to continue developing ChessLab itself; there are many more features I would like to implement. But at a minimum, my ambition is that ChessLab remains usable for a long, long time into the future.

If you use ChessLab in any capacity, you are welcome to contact me with feedback, questions or comments on the program. Oh, and don’t forget to go out and play some chess with a real person over a real chessboard! It’s just a lot more fun!