Beautiful Code
I just finished reading Beautiful Code on the train this morning. After all the attention to writing algorithms and solving interesting programming problems in a beautiful way, what actually struck me most was the second-to-last chapter, "Code in Motion," by a couple of the developers of the Perforce source-code control system. The chapter is actually a discussion and elaboration of a whitepaper on the Perforce website called "Seven Pillars of Pretty Code." The beauty under discussion here has nothing to do with the elegance of algorithms, or domain models, or API's, though it has powerful indirect relationships to all these things. No, this paper is aimed purely at the stylistic beauty of source code, and the way it visually communicates its structure and intent. Or, to quote the opening sentence:
The essence of pretty code is that one can infer much about the code's structure from a glance, without completely reading it.
The paper doesn't need any additional explanation from me. I only want to point out a couple things that really crystallized for me while I read it.
First of all, I've always been fairly adamant about keeping code to 80 columns. This is not necessarily because I do a lot of coding in vi or anything, but for me personally, I tend to like to view multiple "panes" of code side-by-side while I'm working. (At least, that's the most persuasive reason I use against co-workers who use the monitor-width argument to defend their heinously long line-writing practices.) I've always intuited that narrow code is easier to mentally "parse" and comprehend, but I'd never before heard it expressed so beautifully:
... the left edge of the code holds the structure and the right side holds the detail, and big long lines mix zones of structure and detail, confusing the reader.
It was difficult not to jump up out of my seat on the train and shout, "Yes! That's it!" Of course, mindlessly making your code narrower in and of itself won't fix structure/detail problems; but long lines are almost guaranteed to confuse the two. I began to think about some of my stylistic quirks, and realized that almost without fail, they are driven by the structure/detail issue, even if the motivation has been a mostly subconscious one. For example: in general, anything in a comma-separated list always goes on its own line unless the entire list fits compactly and readably on one line. Breaking a list arbitrarily because you've hit the 80-column mark makes it impossible to see at a glance what your parameters are.
This discussion also segues nicely into the problem of indentation. Since I've been programming in Python for many years, this is an issue I've had a long time to think about. Most people coming to Python for the first time complain that the syntactically significant indentation is the one thing that stands in their way of really liking the language. It is frequently claimed by Python evangelists that code that uses syntactic indentation is actually easier to read than code that uses braces or do/end-type control statements to delineate blocks. I agree with this statement up to a point; but in a larger sense it's really beside the point. The more important point is that we should be going out of our way to eliminate it as much as possible:
Forcibly align the main flow of control down the left side, with one level of indentation for if/while/for/do/switch statements. Use break, continue, return, even 'goto' to coerce the code into left-side alignment. Rearrange conditionals so that the block with the quickest exit comes first, and then return (or break, or continue) so that the other leg can continue at the same indentation level.
Of course, it goes without saying, pull out conditional logic into smaller functions and methods wherever appropriate, with their own sensible indentation schemes.
What I love most about Python indentation isn't that short functions are easier to read; it's that long, deeply indented functions are impossible to read, and so you're virtually forced to refactor your code to make it comprehensible.


7 Comments:
Question about your point on long lines: do you have word-wrapping turned on? I don't, and I kind of like how long lines disappear past the right edge, when the information is not very important. It's a kind of suppression of less-important detail.
For example, the following guard clause doesn't need to be seen in its entirety:
if ($_SERVER['REQUEST_METHOD'] != 'POST') { throw new Exception('Not a POST (748876971)'); }
Great post. I used to follow the 80-character limit blindly, and then I rebelled against it for a while with the excuse that we have higher-resolution monitors now. It took me a while before I got back into it to an extent, precisely for the reason you described: allowing you to view two source files side by side.
From your experience, have you seen programmers create bugs in Python due to violating indentation requirements in one way or another? It seems like indentation is a great way to clean up the code from braces and do/end blocks, but it makes me wonder if the code structure becomes fragile and error-prone.
Jonathan: I understand your point, and yes, I would leave word-wrap off, if our code had lines longer than 80 chars in it. :-) Personally, I still wouldn't care to see chopped off lines though.
Andy: I don't know if the bugs I've seen are a direct result of sloppy indentation, so much as a result of code that was too long and nested to understand to begin with. That's the bigger issue, I think. Code like that won't really be helped by cleaner indentation syntax, it just has to be refactored.
In general, I haven't found too many cases of well-written Python code being bitten by indentation bugs.
Fred. I totally agree that Python indentation "inspires" developers to *do the right thing*. From my Java/J2EE to Python and Ruby migration I found that I started to think much more about refactoring longer "blocks" of code in Python and that tendency has followed me to Ruby.
So while I prefer Ruby now (for other reasons), I find that my Python experience has served me well and thoroughly appreciate Python's unique elegance.
Great insights! I love the left/right edge idea. The visual patterns in code are interesting to me in general, so it's cool to see how they can be so neatly related to good coding practices.
Thanks for the post Frederick... I'll have to dig out that chapter.
Post a Comment
<< Home