What do programming and painting have in common?
“He is best known for his work on the programming language Lisp, his former startup Viaweb (later renamed Yahoo! Store), cofounding the influential startup accelerator and seed capital firm Y Combinator, his blog, and Hacker News.”
Published in 2004, the book is almost two decades old. Yet, I found it still full of insights about computer programming and building startups. In this post, I’m going to summarize and comment on a few key ideas about programming from this book. I’ll save his arguments for starting companies and his insights into product development for another post.
Programming is and should be more like painting
This analogy between programming and painting is one of the central ideas in this book. The commonality between the two activities starts with their creative rather than scientific nature:
“What hackers and painters have in common is that they’re both makers. Along with composers, architects, and writers, what hackers and painters are trying to do is make good things. They’re not doing research per se, though if in the course of trying to make good things they discover some new technique, so much better.”
This point might seem obvious today, but it’s a good reminder that a formal training in science (including computer science) and mathematics are not required to enjoy programming either as a hobby or as a profession. By drawing an analogy between programming and other, older creative activities, Graham implies that we can borrow techniques and principles from those fields to improve the practice of programming and the design of programming tools. This line of thinking opens many doors, some of which are discussed later in the book.
Programming often feels like sketching and should be supported as so
If you’re an experienced programmer, should you feel bad if it takes you multiple tries to figure out a program for a given problem? There is a myth that good programmers know what they are doing and can work out a program in their head, just like someone good at Math ought to be able to wrangle numbers quickly by heart.
Graham believes this myth must be busted. Not only did he recognize that he didn’t program that way, but he also thought there was nothing wrong with figuring out a program iteratively, drawing again on the analogy between programming and painting.
“You should figure out programs as you’re writing them, just as writers and painters and architects do.”
Acknowledging how programmers actually work is a shift of perspective that has had far reaching implications for the design of programming languages and tools.
“It means that a programming language should, above all, be malleable. A programming language is for thinking of programs, not for expressing programs you’ve already thought of. It should be a pencil, not a pen.”
In particular, Graham argues that one of the properties of programming languages that could make “sketching” programs easier is dynamic typing, the ability to use variables immediately without specifying their data types upfront.
Was Graham wrong about dynamic typing? Well, I think his general point is still valid, but the cost and benefit of static typing has changed a bit over time. First, many modern languages can infer a type from the initial value assigned to a variable during its declaration. This feature reduces the cost of writing out the type names explicitly. Second, the advancement in static program analysis techniques made it possible to catch many programming errors and offer accurate code completion suggestions as the programmer writes the code, when the program language is statically typed. This dramatically increased the benefit of static typing, making it more attractive.
Nonetheless, static typing has not won in every domain and use case, especially in places where programming is more often used for exploration rather than production purposes. For example, Python is still dynamically typed, and it’s more popular than ever, especially in Data Science. The tradeoff between being safe and robust and being agile and sloppy is likely to remain a fundamental tension in programming language design.
An ideal programming language breaks down the boundary between prototyping and production
“A good programming language should, like oil paint, make it easy to change your mind”
Graham points out that oil paint became popular because it’s easy to go from a rough sketch to the finished paint all on the same canvas and using the same set of tools, by painting over existing strokes.
“What made oil paint so exciting, when it first became popular in the fifteenth century, was that you could make the finished work from the prototype.
This property is often difficult to achieve in programming, because what makes a tool great for prototyping is often at odds with what makes a tool great for implementing production quality software. Doing this well also requires the designer of the programming language and tooling to pay a lot of attention to supporting the evolution of programs, including refactoring, versioning, testing, and reusing. Thus, it’s not enough to judge a programming language by how nice the finished program looks. What matters is the whole lifecycle of the program, as Graham states:
“So the test of a language is not simply how clean the finished program looks in it, but how clean the path to the finished program was.”
The painting metaphor of programming has had a profound impact over the last 20 years. It’s unsurprising that this idea is reflected more often in the evolution of UI programming. For example, Flutter, the UI toolkit I work on, is literally sold on a developer experience likened to painting a UI with code. A cornerstone of the painting-like experience is hot reload, a feature to enable the programmer to instantly see incremental changes made to the UI as they edit their code.
What are other examples of applying the painting metaphor to programming? Has this idea been applied to non-UI programming? If you’ve thought about those questions, please leave a comment below.