Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Q&A with Max Kanat-Alexander, Author of "Understanding Software"

Q&A with Max Kanat-Alexander, Author of "Understanding Software"

This item in japanese


Last October Max Kanat-Alexander released his book "Understanding software". The book provides insights into how to keep your software simple, and how you can avoid complex unmaintainable software. You can find our review of the book on this website.

InfoQ reached out to Kanat-Alexander to ask him several questions about his book.

InfoQ: What made you decide to write "Understanding software"?

Max Kanat-Alexander: I go over that a bit in the introduction to the book, but fundamentally, I just want to help people be better programmers. I had a desire to determine what the underlying, fundamental principles of programming were, and then I wanted to share that with the world. And then I wanted to share what I learned after those principles, too--like, how do you apply them, what do you learn after applying them in a large organization for a long time, etc.

InfoQ: For whom is this book intended?

Kanat-Alexander: Every programmer. It might also be interesting to some people who work around the edges of programmers, like engineering managers and product managers, but really it's focused around programmers.

InfoQ: The book doesn't contain a lot of code examples. Is there a specific reason for not including such examples?

Kanat-Alexander: Yeah, in general I don't include a lot of code examples in my writing because I want it to be universal. I try to focus on principles that apply for every programmer in all situations. I don't want the information to either become dated or limited by choosing a particular programming language to give examples in. Sometimes I do give examples in generic programming languages or something that looks a little bit like Python.

Another reason that I've avoided specific examples is that sometimes I'm talking about the refactoring of large systems--the sort of problem you'd encounter in the real world when you're actually working on a large system. In these cases, it can be hard to give a good example without spelling out the whole system across thousands of lines of code. Like, when you want to understand why it's a good idea to refactor a large system, it's hard to give an example without showing you the whole large system. So instead, I provide principles and examples via story and analogy, and then let the programmer develop the experience themselves by applying those principles to a real system.

InfoQ: In the book you talk about the cycle of observation. Can you explain what this is?

Kanat-Alexander: Yeah, in order to program (or probably, in order to do anything) you have to make an observation, then make a decision, and then act on that decision. The reason that I'm pointing this out for programming is that it's particularly relevant to how you interact with your tools as a software engineer. You write some code, then you look at something about that code (like its output, the code itself, the results of a test, etc.), then you make a decision based on that data that you've observed. Finally, you take some action based on that decision, like changing the code, writing a new test, etc. It applies in small ways (you write a line of code, you observe the line you wrote, you decide to write a new one, and then write a new one) all the way up to whole-system ways (you observe a problem, you decide to write a program to fix it, and then you write the program).

There's a lot to say about it in general, which is in the book.

InfoQ: What is your personal opinion to using test driven development as part of keeping this observation cycle small?

Kanat-Alexander: It's a perfectly acceptable way of doing it. It's not the only way, which I think some TDD advocates get confused about. There are a lot of things one could observe and a lot of sequences of action one could choose to take to validly get your observation, decision, and action. Sometimes TDD works, sometimes something else works. What you want is a way to get correct feedback quickly after you take some action. If TDD works for you and doesn't make you sit around and think for a long time without getting a new observation, then I'm all for it.

InfoQ: Are there some off the shelf products you could recommend every programmer that can increase their productivity?

Kanat-Alexander: It's hard to say. That depends so much on the programming language that you use and the way in which you want to program. I'd say rather that there are a series of types of tools that you want to have. You want to have a good editor or IDE that lets you work quickly in the way that you want to work. You need to have a good building tool (like bazel, for example), for languages that need to be built or compiled. You want to have a good test framework and a good test runner. For teams especially, you need some sort of continuous integration system like Jenkins.

There are also tools that you need that don't have any good off-the-shelf versions these days that I know of. For example, it's helpful to have some sort of system that handles your release process. Most companies seem to build those themselves these days, but it's definitely a market hole where a general tool could be released.

And of course, you want a linter, something that tells you about silly mistakes or style issues before you even commit.

On larger projects, it's also good to have some sort of automated refactoring tool. IDEs usually let you do this in the ways that are most commonly needed--for example, some system that lets you rename a class or method and updates all the callers to use the new name.

There are lots of other tools that could be useful, but there's a short list of some of them.

InfoQ: Do you have any tips to prevent the second-system effect, where elegant small systems are succeeded by over-engineered bloated systems?

Kanat-Alexander: Yeah, don't rewrite your systems. You almost never need to. It's almost always possible to refactor. See the first book (Code Simplicity) for a checklist that you can use to decide whether to refactor or rewrite.

InfoQ: You also wrote the book "Code simplicity: the fundamentals of software". Would you recommend people start with your newest book or your previous book?

Kanat-Alexander: I suppose it depends on what you're looking for. The first book is a very detailed description of a series of basic laws of software development. It goes from the first fundamentals all the way through a description of why simplicity is important.

The new book, Understanding Software, is an organized series of articles that are all at a higher level, and also build on the experience I gained from applying the principles in Code Simplicity. Some readers might find Understanding Software to be a more practical read than Code Simplicity.

I'd say start with Understanding Software, and if you like it, check out Code Simplicity.

InfoQ: You give some hints on how you can measure the productivity of a programmer. I was wondering what metrics you would use for other people in software teams, like architects or managers?

Kanat-Alexander: Well, that all depends on what the product of those people are. Like, is the architect's product just plans for new software projects, or is it the actual completed software itself? If it's the actual completed software, then you'd measure their output just the same as you measure a programmer's, except you'd probably measure it across the whole technical team that they lead as opposed to just for one individual.

Managers also have to know what their product is. That might be different for each team. If I manage a team of people writing internal developer productivity tools, the metric for my success might be different than if I manage a team writing web-based accounting software for individuals. I might also have some metrics that are people-based, if part of my job involves hiring or growing my team. That's not really my speciality, so I wouldn't propose specific metrics there, other than to say that you want to be sure you're measuring some sort of product if you want to know about your productivity.

InfoQ: What is the most terrible code that you ever encountered, and what was your approach to refactoring it?

Kanat-Alexander: Haha, I know pretty exactly what the worst codebases I've ever encountered were. One was open-source, but I don't want to say what it was because I'm a nice guy and I don't want to insult the developer. Another was a closed-source product that I worked on internally at a company that I worked for, and I can't specifically say what that one was, either. But I can answer the question about refactoring for both of them.

For the open source product, basically I went through and worked first to understand what the program was as a whole. It was all in one file, so I went through and determined that there were large sections to the program. I added some comments that just divided it up into sections and then wrote a brief description at the top of the file that described the sequence of actions the whole program took. That was probably my first commit. Then I went through and found something that I could understand and which seemed easy to fix, and fixed that small thing. Continuing through that progression, I eventually started to end up with something pretty nice.

The closed-source thing, I actually ran through my checklist from Code Simplicity and it was the only project that I ever had to rewrite. So we did a feature-for-feature rewrite with no other changes. That is, we treated it like an experiment where you are only changing one variable at a time. The external interface was exactly the same between the rewrite and the original (though I did fix a few bugs and performance issues along the way). Surprisingly, the rewrite ended up being much more popular, simply because it was so much less buggy and so much faster.

InfoQ: What is the most interesting development to programming productivity you saw in the last couple of years?

Kanat-Alexander: I think the most striking development I've seen over the last few years is the introduction of continuous test runners. These are tools that re-compile and re-run your tests every single time you save a file. It changes development cultures dramatically. It works a lot better in interpreted languages like JavaScript or Python, of course, since there isn't a compilation step. But it works pretty well in Java and Go, too. I'd say that continuous test runners that finish within two seconds after saving are the holy grail of developer productivity tools these days. Imagine that every single time you saved your file, you knew clearly (with clear feedback and easy-to-debug test failures) whether or not your whole system was working. What would that do to your testing culture? And what would happen to the stability of your system? And wouldn't you feel more free to refactor? Anyhow, it's quite remarkable what it does to a team's culture.

About the book author

 Max Kanat-Alexander is the Tech Lead for Code Health at Google. He blogs at and is the author of the books Understanding Software and Code Simplicity. You can follow him on Twitter at @mkanat.


Rate this Article


Educational Content

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p