Tuesday, December 04, 2007

peeve no. 252 is artless programming

I intended to ramble on for a bit about how readability/ease of understanding is not at all guaranteed by the mere use of a runtime-typed language, but then I recognized that the point I planned to make was in a sense the opposite of a previous peeve, no. "251": equating programming and art. The main thrust of 251 is that programmers don't need to babble on about pretty code and being artists when each programming task (ideally) has an objective purpose and objective obstacles known as bugs. Regardless of the opinions of a few folks, code is likely to be far more appreciated for fewer bugs than for beauty.

However, I can't deny the existence of programming style, nor can I ignore its manifestation or absence in any particular piece of code. The level of style exhibited by code has been analyzed and quantified in a few ways: lists of code "smells", program-structure calculations such as cyclomatic complexity, lint-like tools for flagging potential problems (tried JSLint, by the way?), and, of course, automated style-enforcement programs. The sense of style I am describing includes and goes beyond all those.

It also goes beyond bug reduction, the province of 251. Code listings A and B can be equally bug-free, but the level of style in A can still be unmistakably superior to B. Style is part of what Code Complete tries to communicate. Duplicated code has less style than modular code. Cryptic variable names have less style than informative variable names; so do verbose variable names. Objects and functions that overlap and do too much have less style than objects and functions with clear-cut responsibilities. On the other hand, style indicators are more what you'd call guidelines than actual rules, because style is an elusive concept which escapes hard definition.

One example of the difference between code with style and code without style has been burned into my memory. In one of my first few undergraduate classes, the professor divided the students into three groups to write a pseudo-code algorithm for translating a day of the month into a day of the week, but only for one specified month. Thanks to my influence (I was the first one to suggest it, anyway), the group I was in used the modulus operator (%) as part of the algorithm. One or both of the other groups made an algorithm without the modulus operator, a patchwork algorithm having several simple "if" statements my group's algorithm did not. All the algorithms solved the (trivial) problem of producing the correct output for each input; the benefit of several people to mentally trace/check the code was probably why the students broke into groups in the first place. Need I state which of the algorithms had the most style, regardless of my all-too-obvious bias?

Here's another quick example, from a few days ago. Out of curiosity, I was looking over some checked-in code. A utility class contained a handful of methods. One of those methods had many complicated steps. In defense of the code's style level, the method's steps were sensibly grouped into a series of "helper" methods, called in succession. The gaffe was the visibility of those helper methods: public. Is it likely that other code would try to call any of those helper methods individually? Is it even likely that other code would use that narrowly-applicable utility class? No on both counts. The public visibility of the helper methods causes no bugs, and realistically speaking will never result in bugs. Nevertheless, objects that "overshare" a contract/interface to other code represent poor style.

The programmer who checked in this code is not dumb, yet he had a style "blind spot". Style is subjective, but it can be learned. Constructively-minded code reviews should put an emphasis on improving the style of everyone involved.

If you've read Zen and the Art of Motorcycle Maintenance, you may also have noticed that its conclusions about language rhetoric resemble the above conclusions about programming style. Quality craftsmanship can arise from the mental melding of craftsman and material. It's neither objective nor subjective, neither art nor science. A common expression of programmers is a language or framework "fitting my brain". Artless programming proceeds without the attempt to achieve this deep awareness.

No comments:

Post a Comment