It seems I don't recognize beautiful code. I only recognize ugliness...maybe beauty can be defined as the absence of ugliness? FWIW, here are some of my pet peeves. Good holy war material, here, but I suspect 70% of you agree with 70% of it (giving a total agreement percentage of 49%, which means I must be disagreeable):
- D. R. Y. (Don't Repeat Yourself.) Seeing multiple functions that do the same things is ugly. Seeing unrolled loops is ugly (but acceptable if they were truly in bottleneck functions). Seeing big switch statements where each case does mostly the same thing, that could have used formulae or lookup tables instead, ugly. In general, fewer lines of code that do the same thing is better, assuming you're not getting cute with C idioms.
- Functional-ness. Seeing the results of simple calculations get cached is hideous to me--almost always a premature optimization--but it seems to be a knee-jerk reaction of some coders to cache calculations before they've even seen if it's a performance bottleneck or not. When the entity enters the rectangle they store entityInRect = true rather than writing an IsEntityInRect() function that, while marginally but immaterially slower, is much less likely to have state bugs.
- Clarity and "Simple As Possible But No Simpler" - with the most beautiful code it's obvious how it works from a glance. Extra levels of indirection and abstraction can murk it up, as can extra cached data. But overly simplifying your data or your abstraction will create reams of code that handles the extra complexities and special cases that your overly simple data layout didn't capture. Still, my approach is usually to start simple and refactor when I realize I've gone too simple.
- Organization. I'm awfully fond of Lakos' technique of putting a 3 or 4 letter prefix before your modules' names to categorize them. I've learned to hate using Visual C++'s filters to categorize code (a Graphics filter, Audio filter, etcetera) because it makes it hard for rookies (and some vets) to know where modules are. If you have so many files you need to use the filters, the best trick is something David Cook showed me, have a filter for each letter of the alphabet. Combined with Lakos, you get categorization *and* easy-to-find files. ( Side note: one thing I use filters for is separating the files that need precompiled headers from the files that don't.) And organization includes...
- No monolithic modules. Michael Enright, my lead when I worked briefly for GameTek, once told me, "If I see a module more than 1000 lines long, I cut it in half. Then I cut the programmer in half." But maybe that's overdoing it. Looking through my code, seems like 5000 seems like my limit. (The SchizoidEnemy file, which describes all the behavior, real and cosmetic, for the Schizoid enemies, is 4000 - could have fairly easily been broken down to one file per enemy, though, for More Beauty.) If you're over 5000 you're definitely not breaking down your problem into tractable subproblems.
- Formatting. Does this really matter? Isn't the beauty deeper than that, in what the code represents? I don't think so. You could have meaningless text - some arrangements of that text are going to be more beautiful than other arrangements. And, going out on a limb here, with meaningful text the more beautiful arrangements are going to be correlated with more beautiful function.
I don't care about number of spaces per tab as long as it's between 2 and 8. I don't care about underscores or intercaps as long as they're not mixed - pick one and stick with it. I like a little whitespace. I like to see brackets on their own lines. Generally I'm happy with the autoformat that Visual does. I like to see lines that fit on the screen or on a landscape printout. I like more than a single linefeed between functions, but don't need a whole comment block.
- Eschew #if and #ifdef. They look ugly because they are ugly. There's probably implementation crud you should be hiding there.



I'm pretty sure I never actually cut a programmer in half.
I have written a lot of code where entire suites of classes are put together in one file and in the process leaned HEAVILY on the IDE to navigate the code. As soon as the code hits the source repository it has to be divided up into manageable chunks for the sake of the team. Usually cvs/svn/git can manage the merges in one file well enough but it's troublesome to have multiple workers hitting the same file.
In certain articles about IBM's VisualAge IDE, it was said each C++ method was put in its own storage (said to be a database rather than a file system). This didn't work perfectly with all preexisting programs, but it makes you think about how our source code organization methods reflect the development process better than they reflect the code's structure.
C2 Wiki article on VisualAge has comments that go off in this vein.
Posted by: Mike | August 03, 2009 at 11:35 PM
http://gwaredd.blogspot.com/2005/08/good-code.html
Posted by: Tom | August 04, 2009 at 09:30 AM
I think it's also to the programmer's advantage to write organized and clean code. Not only in fear of getting cut in half.
Organized code means organized thinking.
Posted by: Michel Carroll | October 30, 2009 at 12:18 PM