CUPID - for joyful coding
This website is based on an article by Daniel Terhorst-North, describing properties of joyful code.
I believe that there are properties or characteristics of software that make it a joy to work with. The more your code has these qualities, the more joyful it is to work with; but everything is a tradeoff so you should always consider your context.
There are likely many of these properties, overlapping and interrelating, and there are many ways to describe them. I have chosen five that underpin much of what I care about in code. There is a diminishing return; five are enough to make a handy acronym, and few enough to remember.
The five CUPID properties are:
- Composable: plays well with others
- Unix philosophy: does one thing well
- Predictable: does what you expect
- Idiomatic: feels natural
- Domain-based: the code models the problem domain in language and structure
Some code is a delight to work with. You know how to find what you need to work on. You know how to make the change you need. The code is easy to navigate, easy to understand, easy to reason about. You feel confident that your change will have the effect you wanted without any undue side-effects. The code guides you, invites you to look around. The programmer(s) who came before you cared about the person who would come along later, maybe because they realised that the programmer who came along later might be them!
In his seminal book, “Refactoring”, Martin Fowler says:
“Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
—Refactoring, Martin Fowler with Kent Beck, 1996
I read this in the early 2000s and his words turned my programming world on its head. What if good programming is about making code understandable to other humans? What if one of those humans is future me? That sounded like something to aspire to.
But while “understandable” might be a noble aspiration, it is not that high a bar! Around the same time that Martin was writing about refactoring, computing pioneer Richard P. Gabriel described the idea of code being habitable:
“Habitability is the characteristic of source code that enables [people] to understand its construction and intentions and to change it comfortably and confidently.
“Habitability makes a place liveable, like home.”
This feels more like something to strive for. How nice would it be to feel comfortable and confident changing other people’s code? And if we can make code habitable, what about joyful? Is it possible for a codebase to fill you with joy?
If you spend your working days programming, then navigating and manipulating a codebase defines your user experience. You can experience surprise, frustration, dread, anticipation, helplessness, hope, joy, all because of the choices that earlier programmers made in the codebase.
If we assume it is possible for a codebase to be joyful, is each codebase its own special snowflake whose impact on your psyche is unique? Or can we articulate what makes it joyful, and offer a path towards increasing the joy in the code that we touch?
I believe code that possesses more of these properties—of composability, Unix philosophy, predictability, or being idiomatic or domain-based—is more pleasing to work with than code that does not. While I value each characteristic independently, I find they are mutually reinforcing.
Code that is both composable and comprehensive—doing one thing well—is like a reliable friend. Idiomatic code feels familiar even though you have never seen it before. Predictable code gives you spare cycles to concentrate on surprises elsewhere. Domain-based code minimises the cognitive distance from need to solution. Moving code towards the “centre” of any of these properties leaves it better than you found it.
Because CUPID is a backronym, I had several candidates for each letter. I chose these five because they feel “foundational” somehow; we can derive all the other candidate properties from these. Future articles will explore some of the shortlist properties that did not make the cut, and look at how they are natural consequences of writing CUPID software.
I am keen to hear of people’s adventures with CUPID. I am already hearing about teams using these properties to assess their code, and to develop strategies to clean up legacy codebases, and I cannot wait to hear experience reports and case studies. In the meantime I want to go deeper with CUPID, exploring each of the properties in turn, to see what else has been hiding in plain sight.
I recommend anyone involved in software development, not just programmers, read this short essay. It is a profound and beautiful piece of writing. ↩︎