Call it a crisis of faith.
I'm sitting today, looking at some code, and part of me is disgusted. I know that I or any number of people could've done better with this code, but, well, we didn't. The code is what it is. Some of the methods are long, some of the classes are big. The code isn't a shambles. There are some very nicely factored methods that are almost crystalline in their structure, and they brighten up the rest of the code. All in all, we could've done better, but we didn't.
There comes a point when you look at something that has continually annoyed you and you realize that no, it isn't a complete mess. Yes, it's a bit disheveled, but there's a sort of beauty there. It's organic, and organic things have their own structure and form. They start simple, grow into use, and then they start to age and deteriorate. I think that anyone who has programmed for a while can map that biological cycle to code. If you're prone to be distressed by it, you have the opinion that code just doesn't die soon enough for your tastes. I know I've felt that way many times. But, seriously, if we can see this sort of biological quality in our code, why are we so upset by it? Methods and classes growing over time.. it should be the most natural thing in the world, shouldn't it?
I guess it comes down to our orientation to our code. Code isn't like a pet that we can admire for it's lovable qualities (or, maybe it is, we often have to clean up after it). Code is more like a working material. We have to understand it and cast our thoughts in it. When we can't shape it easily, it frustrates us.
A while back, Larry Wall described Perl as a post-modern programming language. What he meant was that Perl doesn't say that there is just one right way to do things. When you look at the language you realize that you can do just about anything you want to do, and you can do it in at least three or four ways. It's a cool idea, but.. you know... give me a real simple language with only one way of doing things. Give me a code base where all of the methods and classes are well factored and well named. Many of us like order because it just makes things easier. Every little bit of order is a like a little promise. It says "If you understand this one thing, you'll understand more. It all means sense.. it really does."
So, we have this tension between what we want, and what code seems to want to become. We strive for order, but we're surrounded by entropy. Giving up doesn't seem right but neither does working against the grain of software.
Maybe there is another way.

Comments (9)
Someone I was talking to (on facebook) recently described programming as 'creative/architectural', which I thought was a fine choice of two words to put together.
What I take from this is that, in good programming, the structures imposed by the language work to the advantage of a creative programmer, and that the process is truly creative because of this. (Kind of in the same way that a deep internalising of musical structure, theory and muscle memory for a particular instrument makes for creative music... though, yes, that's a slightly w*nky comparison, sorry!)
I like Java because of this, coz it does restrict, but in the right places - leaving me free to make the architectural choices I want, for right or wrong, and learn from others' best practice.
Wibble wibble.
Posted by Dan | August 28, 2007 7:04 PM
Yes, there's a charm with very expressive languages, but the maintenance aspect is huge compared with strict rules.
When I write code, I try to think about the next person who has to maintain it, the more expressive and obscure, the harder will it be to fix problems and extend the functionality. This is also true for ancient optimization tricks, where the compiler usually could optimize code even if the variable is defined instead of directly assigned, and so on.
Posted by Kent Sandvik | August 28, 2007 8:50 PM
Kent:
Yes, I've been thinking about that a lot. It does seem like there is tension between expressivity and maintenance. I keep wondering what this means for language design. I imagine that if we had more restrictive languages, recovery might be easier.
I don't have any answers but I know that I will be very happy the first time that I hear of a language designer giving substantial weight to maintenance considerations.
Posted by Michael Feathers | August 29, 2007 3:51 AM
I think the most elegant and beautiful solutions are ones that address the problem in the most natural way possible. Sometimes that means rigid structures, conventions, and best practices. Sometimes it requires a more radical approach. Still others, it may simple be a short, terse, difficult-to-understand expression that moves a mountain with little effort.
Beauty in my understanding is not the elegance of the tools, but the solution to the problem. Choosing the right tools, making the right trade-offs, and having a clear understanding of the problem -- these are the most important factors. When the end product feels natural and right; that's beauty.
Sometimes in the course of developing a project, there are bits that are hacked together and others that are well-refined. Look at the context -- sometimes the code gets that way because of rushed deadlines or constantly revised requirements. It may look rough, but if a solution was still found and holds together despite those external forces, a part of me would still consider it beautiful in some way.
Posted by James | August 29, 2007 11:12 AM
The problem here; is that the purpose of code, is to convert machine language into a human language. The premise is inherently flawed.
Human language is a terrible tool for describing and organizing the logical structures we use in computer code. Watch any news program, listen to any politician. We can't even all agree on a definition of "Life". Few humans can grasp the flexible, squishy parameters with which we define our words - and we expect computers to grasp that? In the field of Discrete Math, you find different notation for expressing "therefore" in different contexts. And these are the math geeks that don't agree amongst themselves. So coders are going to someday agree on a concept like "beautiful code"?
I was explaining number systems to my 11 year old daughter yesterday, who is starting a new year in school, and more difficult math concepts, and trying to understand base-5 counting, and base-7 counting, etc. I explained that computers only have two fingers to count with. She said; "Computers lives must be so simple." I replied; "Yeah, until they have to talk to us complicated, 10-fingered people."
Posted by Neil Prestemon | August 29, 2007 1:29 PM
So true that code is "organic, and organic things have their own structure and form. They start simple, grow into use, and then they start to age and deteriorate."
You make a beautiful prototype/ proof of concept. But this thing is sterile and only exists for your fellow coders to wonder at. It is not useful except as an academic exercise.
It's only once the code gets used, and that use shapes how the code grows through the rescoping of functionality that it takes on some character and its beauty changes.
But it's still beautiful.
Great article.
Posted by Simon | August 29, 2007 2:38 PM
My understanding of the rationale behind Perl's flexibility is that it allows you to write code where the main execution path(s) is more obvious.
e.g. Only the programmer knows when he is testing a return code for an error or as the main path, but at least in Perl the error handling can look different. Or rather, the main path can be made to stand out.
Let a gas-pipe look like a gas-pipe.
FWIW I don't think Perl helps much...
In my opinion programmers just forget what their code is for, and so:
- fix a bug
- handle an exception
- add a feature
That's where most of their time is spent (and most of their lines of code), and after a while that's what the code looks like - a list of bug fixes, exception handlers, and "just-one-little-feature".
But what is the code really meant to do? That's what the person who inherits the code will be asking.
Posted by Sean | August 30, 2007 9:29 PM
All too often maintainability and expressiveness are seen as a zero-sum game. A trade off. A messy, expressive language or a terse, ordered language. I don't see it that way.
Programming is an attempt to take human thinking and explain it to a computer. It is an attempt to codify reality. The less translation you have to do between reality and the computer the better. The more flexible your language, the less you'll have to twist the rules of reality to fit the limitations of your language.
On the flip side, flexible languages require a whole lot of experience and restraint to know what bits to use when (and what bits to never use). Perl: discipline not included, some assembly required.
Inflexible languages effectively have the language designer's ideas about best practices hard wired. This means less thinking on the part of the programmer... until you need to do something the designer didn't think of. Or maybe best practices have changed since the language was designed. At a certain point the programmer's needs will clash with what the language offers and the result will be a frustrating mess.
How do you reconcile this? Encapsulation. Take the most fantastic and clever code in the universe that only an expert would understand, wrap a method around it with a good name and some documentation and it doesn't matter how its written. You get your flexibility and you get your simplicity. Much of the best code on CPAN follows this principle.
Sufficiently advanced technology may be indistinguishable from magic, but sufficiently advanced magic can be made indistinguishable from technology.
Posted by Michael Schwern | August 31, 2007 2:31 AM
I think making a code is not easy, as well as understanding it.So we must think of other people that will, ikf ever needed, use it in the future.....
Posted by Ellaine | August 31, 2007 6:59 AM