The Science of Painting and the Art of Programming
We tend to treat programming as a science or engineering. But is that all that it is?
A computer program is a recipe of steps to perform. Together these steps should solve a problem or perform a task. This seems very different from making a painting where there is seemingly no rule that has to be followed. What is a compile error on a painting?
Yet to the pedantic who gets too hung up on the concrete, it is hard to see any relation: Painting is an art and programming is an engineering discipline.
By now you may wonder why I am making the comparison between painting and programing. It is actually due to Paul Graham originally making that comparison in his essay Hackers and Painters.
This naturally spawned some rebuttals.
To me it doesn’t really matter what you compare it to. Paining is a bit arbitrary, but still useful as a way of talking about how both art forms and engineering contains aspects of each other.
Programming is as Much for Humans as for Computers
We use programming languages to write code, instructing computers to do tasks we want done. However, there are an infinite number of ways that we could do this.
While we obviously want our programs to be fast and correct, one of the most important aspects of programming is to write code that other programmers can read.
You write code for others to read. Making readable code is more of an art, than a science.
In many ways, you are writing a sort of essay that has two very different audiences. The first is the computer, which you want to read what you wrote and carry out the tasks you intended it to do. Computers don’t care about how you name your variables as long as they are consistent. It doesn’t care about
snake_case. Nor does it even care whether you factored your code neatly into separate functions or not.
The second audience are humans, of which you are one. Code has to be written so that others — including yourself — can read and understand the code you wrote two weeks ago. Not only that, they should also be able to easily modify this code.
Yes, there are certainly engineering ideas going into this. But what makes code easy to read and follow is often a question of taste not all that different from writing a novel or the story you are reading right now.
When I am writing on Medium, I am trying communicate my thoughts and ideas to the reader in a clear manner. In fact when I began writing, the future reader was in fact often myself. I would learn some tricky task, only to discover a couple of months later that I had almost entirely forgotten how to do it. The process of writing code has many similarities. When we begin, the main reader is often yourself. You give functions and variables sensible names so you can remember that they are for.
You try to write in a style that both carries out the correct task as well as communicates effectively to the human reader what the code is doing. IBM had an interesting evaluation of this. They tried to measure coder productivity by looking at how much code was being used and reused by other developers 10 years after it got created.
You have to take this with a grain of salt, as it is based on my recollection of reading about this many years ago. What I recall, however, was that people with more of a soft science background had better outcomes than the more hardcore mathematicians and engineers. The reason was simply because their code was written more for the human reader and could thus be better understood and reused years later.
This actually matches my own personal experience:
I recall at least two occasions where large chunks of code made by some very brilliant and “productive” developers were simply dumped.
Why? The code may have solved a problem, but was simply not readable to the average developer. Both were the kind of technically brilliant guys who neither commented code, nor attempted to structure the code in any neat and readable way. Their main concern seemed to have been more about making what would be efficient for the machine or what made them solve their problem fastest.
Thus the developer who looks productive this week, or this month may not be very productive measured on a longer time scale. The developer who wrote half as much code will have contributed more to a company if his or her code is still in use 10 years later, while the code of the “brilliant” engineer has to be dumped due to its complexity and lack of readability.
These problems are not unique to programming. It is many of the same issues I tackle when working on GUI design. Many combinations of buttons and menus can get the correct task done. But some combinations are more user friendly. The same applies to physical devices. Computer themselves, microwaves, dishwashers. There is the simple engineering requirement of getting the dishwasher to wash your dishes clean. But there is also an art into designing the product so that it can be easily operated. This is not just a question of arrangement of buttons but also in how the trays are designed and how you feed in the detergent.
Thus I will reject this simplistic idea that painting and programming are completely opposite universes. In fact, if we look at the history of painting, the similarities may be stronger than apparent at first glance.
The Science and History of Painting
With modern art, it may seem like painting is just about throwing whatever blobs of paint onto a canvas you like. There are no rules. You do whatever you like. It isn’t like programming at all, which must followed strict rules.
Yet it isn’t really as different as some people like to make it. If, for example, one looks at the great painters from history such as Leonardo da Vinci, Michelangelo or Dutch Masters such as Rembrandt, they didn’t just throw paint around and then put it into a gallery. Rather, they typically painted portraits — something that does not allow you to throw random blobs of paint onto a canvas. Or at least not if you want a happy customer.
Similarly, when developers make a program we have a customer and some sort of spec for what needs to be made. Painters also could be said to have had a specification that they had to follow. Somebody wanted their portrait painted in particular surroundings. There might even have been requests for the painting to invoke certain associations or impressions.
Thus painters did not do whatever they wanted any more than a programmer does. Nor was painting strictly divorced from science the way people think about it today. It was not unusual that painters were equally good scientists and engineers. Just look at Leonardo da Vinci.
This is no coincidence. Today painting is all about expressing oneself. But one has to remember that paining and drawing was as much a substitute for the fact that one did not have photography in historical times. Thus investigating how light reflected, how color separated, etc., was scientific work that great painters often had to get quite involved with. In fact, studies show that the really great leaps in quality of paintings happened when painters such as the Dutch masters began using lenses to mimic what happens inside a camera. They would project the image onto their canvas and paint on top. Essentially they mimicked what happens inside film cameras when the film gets exposed to light through a lens.
For naturalists such as Charles Darwin, mastering the skill of drawing was especially important. You did not get to snap a photo of the animal you discovered in the jungle using your smart phone. Instead you had your sketchbook and you had to carefully observe and draw the animal or plant. Thus understanding things such as proportion and perspective was crucial.
Yes, you might not have gotten compilation errors. But you could still “fail” in very real terms. If you could not accurately reproduce the animals and plants that you observed, then you also failed at doing your job properly. You failed to convey your observations to fellow scientists and the public at large.
Hence drawing and painting is not all that different from programming when seen from a birds-eye perspective. In both cases, we are dealing with craftsmanship. Of course, this applies to a multitude of other professions as well.
Painters and Car Analogies
As a writer, this is something that I struggle with. What we do as programmers or how computers work is quite abstract. You cannot open a computer and see how it works. Nor is it obvious to a lay person what programming is like. Most people don’t write text in such a highly structured manner.
But many other areas struggle with this same problem of conveying the essentials to the lay person. That is why we end up the famous car analogies. Both because everybody has a sense of what a car is and because these analogies have become almost an insider joke, making them often more fun to do.
All analogies are of course always wrong at some level. The painters and hackers analogy is naturally wrong in many ways. But I am always reminded of how my physics teacher taught me electricity by comparing it to water flow. He described the amount of water flowing as the current, and the pressure as the voltage. As he explained it, a battery was more of a water pump than a water tank. You are not draining electrons out of a battery which is full of them. Rather the battery is essentially pumping the same electrons around repeatedly.
It was the first time many of the concepts of electricity finally clicked for me. Thus while analogies are always flawed, some are better than others. What really matters is whether they offer you a way into a difficult to grasp concept. Once you get the fundamentals, you can ditch the analogies and look at the phenomenon directly.
Painting is not the same as coding, but painting is something most of us can intuitively grasp. We have probably all done some water color painting in our lives. Thus painting can be a useful analogy to give outsiders a peek at what the software process is like.
It may even apply to us insiders. At times we get so caught up in the technical details of what we do that we fail to see the bigger picture (pun not intended).
I think a lot of programmers often forget that they are essentially writing stories to other software developers. They are simply using an oddball language to write those stories. Oddball languages which are really picky and pedantic.
The Modern Art of Programming
Even in coding you can end up with something akin to “modern art.” That is, you follow some industry “revolutionary” fad which makes your program incomprehensible to mere mortals. But the pundits and gurus have convinced you that this is the new way to code. The only way.
As with modern art, nobody wants to come forth and say they don’t get any of it or think it is all stupid. They don’t want to be called out and labeled a simpleton.
I know I will get some flak for saying this but as a C/C++ programmer for many years, I must say that modern C++ must be the closest thing to modern art.
Reflections on Design and Communication
I have actually tried writing some different variations on this topic before and given up. I honestly don’t know how to best pitch this. As someone who codes and cares about writing, communication, teaching, UX, usability, clean design and low level technical details, I feel there is a lot to be be said about the intersection between science and art in computing.
On so many occasions when talking with fellow software developers I feel the art, design and psychology aspect is completely overlooked. I still vividly remember a discussion I once had about Apple’s iPhone.
The view was basically that Apple had not done anything because they had not created the touch display, the CPU or the battery. All the parts were already there. In the opinion of these developers, Apple had just assembled the parts. Something anyone could have done.
This betrays a common attitude that design requires no work, or isn’t even there. It is as if you regard some spaghetti code which does the same task as some well-crafted, well-structured and highly readable code as the same thing, just because when executed it does the same.
If you care about the craftsmanship of software development, you know that just getting the code to run and do the intended task is just a small part of programming. Making sure that it is written so it can easily be understood, modified and tested is crucial. Getting there has much in common with what is required from tasteful design.