Home > Development > Professional code aesthetics

Professional code aesthetics

September 15th, 2008

At the c4[2] conference, Buzz Andersen said in his talk Apple to Indie:

Professional code is ugly

If I understood him correctly, as he started to work at Apple, he was expecting the code there to be beautiful. Paraphrasing: These guys are the keepers of the APIs. The code they write has to be beautiful!

If you are reading this, you probably believe that you, too, can write beautiful (or at least, aesthetically pleasing) code. And you are probably correct.

Your code probably starts out as beautiful, or as beautiful as you can make it. You are the only one working on it. It is your design, your vision. You are proud of it. This is good.

If you are part of a team, your code probably gets in a common source code repository. Then your colleagues start to work on it, because a of an edge case you had not anticipated. They are motivated by the best intentions, but unfortunately, smallest common denominator sets in. “Monkey-see, monkey-do”-type code cannot lead to beautiful code: it has to be designed.

Design is hard

Design is hard. It’s also hard to maintain as you are fighting barbarians at the gate: deadlines, colleagues, new features, even bugs.

Good design is obvious, especially in hindsight. It can be enforced by the design patterns, the unit tests, the compiler macros or the C++ templates.


Your code also has to interface with other code, be it the operating system, or the Perl script that talks to your printer-plotter over a RS-232 connection.

Maybe you control the interface, and can keep the design. Usually, you don’t. And then you’re stuck interfacing with ugly code, which tends to infect your code by imposing its own constraints. Lowest common denominator again.

Changing requirements

No code can handle everything. There are some extreme cases where requirements don’t change, and the person/team in charge of those requirement know everything in advance. If that is the case, congratulations, you can use the waterfall development model. The rest of us have to deal with change.

When a change in requirements happens, maybe your design can accomodate it, maybe not. Usually, you have to refactor.


You may have some budget for refactoring? Well-planned. But remember, the ultimate goal of refactoring is to ensure that your code performs in the same way as before. This is a win for you, and future versions of your product, but does nothing for the current customer.

The “business case” for refactoring tends to diminish with time. As deadlines loom, those two months that you had planned to rewrite the print engine will fly by, and if you are not 80% done in 20% of the time, you should seriously think about how important this is. Because if you are committing your whole team for two months, that’s a lot of (wo)manpower. And if you take a subset of the team, they might feel like they are left behind, working on something that has no user-visible impact while someone else works on a whiz-bang shiny feature.

Refactoring is not undertaken lightly. There is a very distinct possibility that your refactoring will break the app. One way to alleviate those concerns is to use unit tests. When automated (and run as often as possible, for instance on every check-in), they can increase your confidence that you did not break anything important by re-writing a critical subsection of your code.

Test-driven development (TDD)

I love TDD. I love writing a test for a bug, exposing it and fixing the code to make the test pass. I also love to develop “framework-level” features, for example File I/O, using tests to create, open, parse, and save files in the new disk or network format.

However, test-driven development leads to utilitarian code. Literally, “write enough code to cover the unit tests, and then no more.”. While some interesting designs may arise from this, more often than not the code is textbook-like, driven by the requirements imposed by the tests.


Any of these features can lead to ugly code:

  • Several people working on it
  • Changing requirements
  • Interfacing to non-beautiful code
  • Test-driven code

I would be hard-pressed to find some code that does not have at least one of these characteristics.

So I agree with Buzz. Professional code is ugly. When you see beautiful code (and you will know when you see it), treat it like a endangered species. Protect it, nourish it, make it regain some strength. Educate others about it. Because one day you will look at it again and think proudly: this is beautiful code.

Categories: Development Tags:
  1. July 29th, 2009 at 20:49 | #1

    I don’t agree with you.

    I think that writing a good looking code is same skill as everything else.

    I think that architecture has its beginnnings in aesthetics.

    It’s simple philosophical statement.

    But philosophy is the source of all the knowledge.


  2. July 29th, 2009 at 21:35 | #2

    I agree that writing good code takes skill, and good architecture. My observation is that the external pressures applied to programmers lead to ugly code. Once you realize that, you are on the path to enlightenment 🙂

  3. July 30th, 2009 at 06:26 | #3

    O .. sorry

    So I’ve somewhere lost the point in the article or it may be unclear in some way.

    Yes .. this is the important matter that pressure is being made and because of that pressure and inability to manage with it most of the programmers are producing ugly code.

    But once you start to see that pressure and you gain skills in managing it another story begings 🙂

    There are few ways of controlling ugly code, which is becoming “construction debt” and finally what we call a waste:

    * you need a good PM which is negotiating better timings for you and keeping an eye on code quality
    * you need to gain negotiation skills by yourself

    one does not exclude the other

    I may come here with some article link created as an answer to this one in some time. As usually later that we would expect 😉


Comments are closed.