Beauty as objectification of quality

Beautiful code is good. But how do we get from the design patterns of nominalisation or separation of responsibility to the idea that beautiful code is good?

Beautiful code is beautiful only when we consider the viewpoint of genetic evaluation. Its ability to reproduce makes it beautiful. Its ability to survive makes it good. Whether it’s fit for purpose is part of it. Whether it’s an environment in which other things can happily exist also contributes. Companies with bad code tend to go out of business, but it’s sometimes circularly defined. The code is defined as bad because it’s non-surviving; the business didn’t survive. Companies with good code can go out of business too, but that’s a weakest link issue, where an accident from a different domain cuts the life of an otherwise healthy organisation short.

It’s a very circular definition, but it’s just the same as how we evaluate and define good or high-quality for biological systems. We measure a genome’s effectiveness by how successful the organism it generates is at reproducing. If the organism dies, its genome has failed. If you assume poor genes lead to a weaker and less successful organism, you have already accepted the circular definition.

Good code will be relative to its environment, and goodness will be a metric of surviving in the face of competition. And yes, if you are shielded from some forms of competition or challenge, your code will likely be deficient in those domains. Without competition, removing poor performers is nearly impossible, as performance won’t be measured meaningfully. If there is no performance baseline, there can be no performance assessment.

But code is unlike DNA. DNA does not have rational authors. The genetic process introduces changes that are simple and random. DNA leverages the power of small, safe changes by combining existing proven DNA. The reason DNA recombination in sexual reproduction is so powerful is that it selects from already proven actions and sequences. Without combination, mutation only allows simple random occurrences to introduce novel sequences. It’s much more likely for a mutation to represent a regression than an improvement. Combinations are more likely to be variations of existing qualities. Think of it as the difference between the likelihood of forming a new valid sentence by using randomly selected words instead of taking random sentences and splicing them together. The chance of obtaining syntactically correct outcomes is still low, but it’s much higher than with single-word changes, and the result is probably more entertaining.

But how does this apply to code? Well, programming tends to consist of providing alternatives to existing code. Our options come from existing code, memory, or creating on demand. But even new code from our imagination is a combination or mutation of something we have experienced. We make changes that are unlikely to be entirely regressive. And if it is, the compiler or tests should catch the problem before it becomes too detrimental.

Programmers can examine existing code and determine what might improve it. Think briefly about how science fiction authors write about genetically engineered creatures; they always seem to be improvements. We modify crops similar to how we make changes in software projects. Introducing plum pox virus genes into plums to increase their resistance is equivalent to importing libraries into our projects.

What does this mean for beautiful code? Well, the ability to tell what the code does and how we can combine it to create improvements is part of what makes it a better survivor, so that aspect must go towards our definition of beautiful. If we can make effective changes safely, we have an advantage over the competition. This aspect, too, must be part of the definition of beautiful code. Whatever makes the source better able to survive and create more of the same source will define what beauty is.

We can’t personally see the beauty, whichever way we look at this. We do not find the most beautiful code attractive. Its properties can only be recognised rationally. We are not struck with awe at beautiful code. And neither are we aroused by a particularly elegant walrus.

But that makes sense because beauty is something in our genes first, our culture second, and only finally in our individual selves. Our sense of beauty starts with our rawest instinct about a thing. We gaze in awe at cliffs and large buildings or from the tops of mountains or the windows on a plane. These senses of beauty (or fear or wonder) are human. Not Western, Eastern, feminine or masculine. All humans see something positive in a warm glow from the window of an abode on a cold night. But this sense is fragile. We logically override the good feeling if our rational self notices a chain-link fence between us and the glow. If we hear alien language from within the building, our suspicion is raised. This is our self overriding the genetic response. Christopher Alexander wanted to avoid this with his paper strip experiment. His abstract test allowed for the most concrete yet honest response.

Why we think things are beautiful can be societal and personal, but whichever layer you choose, beauty is the objectification of quality in that domain. A beautiful dance is a genetic beauty of grace and motion, a cultural beauty of consistency with a pattern, and a personal beauty if you prefer a particular type of dance. What’s useful for us is to see that the quality without a name is closer to pure genetic beauty, even in chairs and paper strips.

But then, we find ourselves in a desperate position. We haven’t been evolving for the last hundred thousand years alongside code. We don’t have any genetic sense of beauty in that domain. So, we cannot see beautiful code at that lowest level. We can only see its beauty in the cultural (coding standards) or personal (familiarity) sense. We may objectively state that some code matches our cultural norms and that we like it, but we can’t assess whether it’s beneficial. Just looking won’t tell us if it’s good. We must act like genetic processes of that domain, making changes and building unquestioningly before seeing it all tumble down to be superseded by a superior piece of code. We can only verify whether code achieved our goals. We can only loosely estimate how likely the code will survive.

This is why software architects have a Herculean job to do. They have to provide a path to follow while blindfolded. Most will choose safety: they will adjust an existing paradigm to fit the purpose, much like how DNA recombination works. Sometimes, the different pieces work out great. Other times, they complicate and cause problems. But then, that’s information to never do that again, effectively neutering the code so it can’t breed more offspring.