What is it with Vertical Space?
Warning: this is a rant, but it's not a pointless one. Enjoy the angst, but don't ignore it.
I happened across some code this week in a pretty normal (one pane-at-a-time, tabbed and tiled) editor. The local coding standard was to put at least one blank line between statements, more if you wanted to separate paragraphs. In addition, there was a documentation standard of placing many lines of comments in a format rather like this:
/*
* first line
*
* second line
*
* third line
*/
I suppose I should be grateful that they didn't add blank lines between the comment "star" lines. I almost wore out the mouse and the desktop trying to find and read two or three functions. Now, what is the sense in that?
Clue for the day: The smart kids are making their code more dense, not less dense. This is one of the reasons that Python doesn't use braces, one reason that the K and R style endures in Java, C, C++, etc. Vertical whitespace should be reserved for the times in which it is effective. For instance, that one line between functions is kinda nice (though in brace-enriched languages one line with nothing but a prace is good enough). In a test, the breaks between "build","operate", and "check" is nice. When you feel that you must write longer functions (and you should consider whether it's the right thing) then breaking code into paragraphs will help you to see more clearly where you should extract methods.
Worse yet, it's the "geocities" version of code. Remember how the kiddies flocked to geocities and tried to make every word on every line stand out? There were a million instances of "dancing baloney" on each page, and a few dozen type faces in a few different point sizes, in different colors. Each word was suffering because all the words around it stood out. It was like trying to be an exhibitionist in a nudist colony. Apply that thinking to your code. Are you trying too hard to make too many things stand out? If so, the ugliness is all that stands out.
Of course, you know I am not fond of comments. I can tolerate some amount of that silliness, but I really cannot stomach 20 lines of comment before each class (half of which are just a star in a left-ish column), and 8 to 10 lines before each and every function. That poor mouse will have to be replaced every 10,000 mouse miles, and that might just be a few months. Or weeks.
If you are doing this, let me make a suggestion: delete all empty lines and all comments from a file. Now, look at the code without apology. If it looks great, then your comments are completely unnecessary. If it doesn't look great, then your comments were hiding the crufty, cruddy nature of your code and you should fix it.
When you're done, delete your comments AGAIN, and only add blank lines where you really, really need them.
As my imaginary friend Wilber T. Fanning will summarize:
- When *everything* stands out, nothing does.
- Every function is not a stand-out function.
- Every line is not a stand-out line, nor is it a paragraph.
- Comments already have a prefix (//, /*, #). That's enough "stand out" for a line that doesn't do anything.
- Whatever readability you gain by spreading the code vertically, you lose more by making people scroll.
!commentForm -r
Charles,
Your post communicates to me that either you've missed some of Tim's points/intent, or I'm giving him too much credit.
My understanding is that Tim is against
1. Any vertical whitespace beyond what a written paper might have ( i.e. one line per paragraph ). I think you would agree that whitespace separating things that actually GO TOGETHER hurts, rather than helps readability.
2. Comments are mostly bad (he says he can tolerate some comments, so we'll say mostly). To get this, you have to read between the lines a bit. Tim is not advocating simply deleting comments and moving on. Rather, you delete comments, and then rewrite and refactor your code until comments are *unnecessary*. That is, instead of having comments explaining what a function does (so you can "decide if it's likely to be involved in the problem at hand"), you give the function a name that explains what it does. If your function is too complicated to describe in a 5 or 6 word name, it's probably too complicated. Consider breaking it down until you can fully describe it using only its name. Finally, if for some reason it's impossible to break down your function in that way, maybe, as a last resort and with much gnashing of teeth, you give it the best name you can and put some comments in. This is a failure, though, because it means that everywhere the function is used, its purpose is, as we have established, unclear (unless you explain the function, in comments, every time it's used).
3. Tim says nothing about advocating single-line "rats nests". His rant is about *unnecessary* vertical space. I think he made this clear in his most recent post. This isn't about cramming things on to a single line that really belong on several lines. It's about eliminating vertical space that contains no information at all. I think he'd argue that the opening bracket of a function, considering that it follows the function header, contains no information useful to the programmer (we know the function starts on the first line after the header).
I happen to mostly agree with Tim. One place I disagree is that a single line between function definitions is enough. I find that a healthy amount of space between definitions helps me to really focus on the function I'm reading. I have a really hard time keeping my eyes off visual clutter. However, I think I feel this way because I work a lot in C++. In C++, when I want the broad view of a class's functionality, I look at its header (where I minimize comments and whitespace). When I want to look into a particular function's logic, I look at the cpp file. I do find myself much more sympathetic to eliminating whitespace or comments BETWEEN functions when I'm working in Java or Matlab, and I sympathise with the elimination of whitespace and comments INTERNAL to function definitions regardless of the language.
You summarize my points well. Probably better than I do (though I'm fond of Wilber's summary). And when you're working in C++ (especially if it's in a M$ environment), I understand why you need a little more whitespace and a few more comments. ;-) - Tim
Your post communicates to me that either you've missed some of Tim's points/intent, or I'm giving him too much credit.
My understanding is that Tim is against
1. Any vertical whitespace beyond what a written paper might have ( i.e. one line per paragraph ). I think you would agree that whitespace separating things that actually GO TOGETHER hurts, rather than helps readability.
2. Comments are mostly bad (he says he can tolerate some comments, so we'll say mostly). To get this, you have to read between the lines a bit. Tim is not advocating simply deleting comments and moving on. Rather, you delete comments, and then rewrite and refactor your code until comments are *unnecessary*. That is, instead of having comments explaining what a function does (so you can "decide if it's likely to be involved in the problem at hand"), you give the function a name that explains what it does. If your function is too complicated to describe in a 5 or 6 word name, it's probably too complicated. Consider breaking it down until you can fully describe it using only its name. Finally, if for some reason it's impossible to break down your function in that way, maybe, as a last resort and with much gnashing of teeth, you give it the best name you can and put some comments in. This is a failure, though, because it means that everywhere the function is used, its purpose is, as we have established, unclear (unless you explain the function, in comments, every time it's used).
3. Tim says nothing about advocating single-line "rats nests". His rant is about *unnecessary* vertical space. I think he made this clear in his most recent post. This isn't about cramming things on to a single line that really belong on several lines. It's about eliminating vertical space that contains no information at all. I think he'd argue that the opening bracket of a function, considering that it follows the function header, contains no information useful to the programmer (we know the function starts on the first line after the header).
I happen to mostly agree with Tim. One place I disagree is that a single line between function definitions is enough. I find that a healthy amount of space between definitions helps me to really focus on the function I'm reading. I have a really hard time keeping my eyes off visual clutter. However, I think I feel this way because I work a lot in C++. In C++, when I want the broad view of a class's functionality, I look at its header (where I minimize comments and whitespace). When I want to look into a particular function's logic, I look at the cpp file. I do find myself much more sympathetic to eliminating whitespace or comments BETWEEN functions when I'm working in Java or Matlab, and I sympathise with the elimination of whitespace and comments INTERNAL to function definitions regardless of the language.
You summarize my points well. Probably better than I do (though I'm fond of Wilber's summary). And when you're working in C++ (especially if it's in a M$ environment), I understand why you need a little more whitespace and a few more comments. ;-) - Tim
Okay, Charles, I think we have failed to communicate. I appreciate the hot button here, though. Hey, it's only fair if we can both rant a little. I guess for each offense, there is an equal and opposite offense to be avoided.
People who maximize clever crammage are also the bane of many, many of my days. I've had to live with some real rats' nests, and I agree it makes everything harder than it has to be and is a waste of time that could have been spent making progress. So clearly, you are right.
On the other hand, people also hide crappy code in comments and blank lines that make you work twice as hard (maybe not three times, but still too hard) to read their code. So clearly, I'm right.
I think that we're both right. There is a sweet spot in the middle, though, and so I offer a revisit of this issue that better explains what I have in mind and what I mean by "more dense" being a good thing.
People who maximize clever crammage are also the bane of many, many of my days. I've had to live with some real rats' nests, and I agree it makes everything harder than it has to be and is a waste of time that could have been spent making progress. So clearly, you are right.
On the other hand, people also hide crappy code in comments and blank lines that make you work twice as hard (maybe not three times, but still too hard) to read their code. So clearly, I'm right.
I think that we're both right. There is a sweet spot in the middle, though, and so I offer a revisit of this issue that better explains what I have in mind and what I mean by "more dense" being a good thing.
Your attitude is one which constantly makes my job harder than it needs to be. I worked for years as a contractor working on code other people had written. I now work in a large corporation and still often work on code others have written.
People like you think they are so smart that comments are unnecessary. In reality, you cause inefficiencies in the operation of large corporations as those of us who have to follow you try to figure out what the heck you were doing and why. You think code should be written in a manner that only other programmers whom you deem to be worthy can work on your code. I think code should be written so that I could hand it to a non-programmer and they could still tell me the basic function of the code.
When code is well commented and uses good variable and function names, I can get in and modify it easily. When the code is written as densly as possible by people like you, it takes two or three times longer. The worst is when you clever folks think you are being so smart by stringing together a bunch of binary logic in a single IF statatement. You may well of left your mark of "Look how smart I am!"; but you did your company a huge disservice as everyone who has to follow you has to take too much time to figure it out.
I agree with Wilber T's summary, but completely disagree with your assertion that you should delete all of your comments. 8 to 10 lines of comments before a 3 line function is overkill; but they are usually warranted in larger functions. If I can just read the comments about what a function is supposed to do, I can quickly decide if it likely to be involved in the problem at hand. The biggest problems with comments from my perspective is that as the code is modified over time, people like you won't take the time to correct the comments and they no longer accuarately represent what the code is doing.
I hope you only work for yourself creating code only you will ever work on.
People like you think they are so smart that comments are unnecessary. In reality, you cause inefficiencies in the operation of large corporations as those of us who have to follow you try to figure out what the heck you were doing and why. You think code should be written in a manner that only other programmers whom you deem to be worthy can work on your code. I think code should be written so that I could hand it to a non-programmer and they could still tell me the basic function of the code.
When code is well commented and uses good variable and function names, I can get in and modify it easily. When the code is written as densly as possible by people like you, it takes two or three times longer. The worst is when you clever folks think you are being so smart by stringing together a bunch of binary logic in a single IF statatement. You may well of left your mark of "Look how smart I am!"; but you did your company a huge disservice as everyone who has to follow you has to take too much time to figure it out.
I agree with Wilber T's summary, but completely disagree with your assertion that you should delete all of your comments. 8 to 10 lines of comments before a 3 line function is overkill; but they are usually warranted in larger functions. If I can just read the comments about what a function is supposed to do, I can quickly decide if it likely to be involved in the problem at hand. The biggest problems with comments from my perspective is that as the code is modified over time, people like you won't take the time to correct the comments and they no longer accuarately represent what the code is doing.
I hope you only work for yourself creating code only you will ever work on.
But when all else is equal, more dense is better than widely-scattered. Well-written small functions double- or triple-spaced and padded by comments so that they are too long are not better and are not as good as the same code grouped tightly. Likewise extraneous (for some value of "extraneous") linefeeds do not make the code more readable, and ultimately detract from readability.
To me, this says that density is a kind of goodness, though clearly not the only kind of goodness.
My preference is that things should be tight vertically with exceptions:
Horizontal space should not be crammed in, but other than indentation there is no need for more than one space
in a row, or a tab in the middle of a line. I can forgive padding comments to start in the same column.
So a short if, while, foreach, for, block, lambda on one line is fine. A short-enough function on one line is fine.
Double-spacing all lines is right out.
Of course, this is not as important as good naming and I never said it was. I just said that it is madness to make functions
too long by adding stupid vertical spaces, and that vertical space should be used carefully, like salt or sugar or cayenne,
so it doesn't overwhelm the flavor of the code. I think that's perfectly reasonable, and I'll stand by it.
Of course, it's aesthetics, and not algorithm. But good algorithm buried in poor formatting is still not good programming.
To me, this says that density is a kind of goodness, though clearly not the only kind of goodness.
My preference is that things should be tight vertically with exceptions:
- Lines should not cross column 72 (or 78, pick one). Line feeds are not extraneous here.
- if there is a natural "paragraph" (build,operate,check being naturally three) then a vertical break is ok.
- A break between functions in a class (unless there is punctuation, like a brace, on a line by itself).
Horizontal space should not be crammed in, but other than indentation there is no need for more than one space
in a row, or a tab in the middle of a line. I can forgive padding comments to start in the same column.
So a short if, while, foreach, for, block, lambda on one line is fine. A short-enough function on one line is fine.
Double-spacing all lines is right out.
Of course, this is not as important as good naming and I never said it was. I just said that it is madness to make functions
too long by adding stupid vertical spaces, and that vertical space should be used carefully, like salt or sugar or cayenne,
so it doesn't overwhelm the flavor of the code. I think that's perfectly reasonable, and I'll stand by it.
Of course, it's aesthetics, and not algorithm. But good algorithm buried in poor formatting is still not good programming.
If you can't see a whole method in your ide, the method is too long. Inconsistantly formatted english prose proves absolutley nothing about the readibilty of well written code.
dense code != good code
True, but good code spread over 3x or 4x as many lines as it actually needs is good code badly formatted, and is harder to read than good code in a more dense format. See my followup post and you'll see that I don't want density as the only measure of good, or as the penultimate. But when the code is good (single effect per line, well-named, idiomatically-correct, etc) then all the unnecessary vertical space needs to come out. -- Tim Ottinger
dense code != good code
True, but good code spread over 3x or 4x as many lines as it actually needs is good code badly formatted, and is harder to read than good code in a more dense format. See my followup post and you'll see that I don't want density as the only measure of good, or as the penultimate. But when the code is good (single effect per line, well-named, idiomatically-correct, etc) then all the unnecessary vertical space needs to come out. -- Tim Ottinger
Whether or not
You have meaningful
Function names and variables
You will find that adding a
Lot of vertical space
Will compound the
Problems of readability
And will be nearly
As bad as a logical inconsistency
By the time you see
A variable used you may
Have forgotten where it
Came from.
You have meaningful
Function names and variables
You will find that adding a
Lot of vertical space
Will compound the
Problems of readability
And will be nearly
As bad as a logical inconsistency
By the time you see
A variable used you may
Have forgotten where it
Came from.
I really prefer K&R style for that reason.. vertical space. It's nice to be able to see a whole method in an IDE. In some codebases that extra newline couldn't possibly matter. In others, where many methods are in the 5-10 line range, it matters a lot.
Single character variable names and short meaningless function names will increase code density and increase the lifespan of keyboards. Will "the smart kids" be proposing this next?
Nah, the smart kids are using languages that express themselves better (ruby, python, groovy, etc), using more expressive names for everything, and avoiding side-effects like it were dental plaque. And I find they're writing smaller, denser code that needs less embellishment to make sense obviating the docs and whitespace entirely and then removing anything that duplicates their ideas or impedes readability. What are the smart kids doing out in your neighborhood? -- Tim Ottinger
Nah, the smart kids are using languages that express themselves better (ruby, python, groovy, etc), using more expressive names for everything, and avoiding side-effects like it were dental plaque. And I find they're writing smaller, denser code that needs less embellishment to make sense obviating the docs and whitespace entirely and then removing anything that duplicates their ideas or impedes readability. What are the smart kids doing out in your neighborhood? -- Tim Ottinger
Add Child Page to VerticalSpace