ArticleS. TimOttinger.
VerticalSpace2 [add child]

Vertical Space Revisited


Okay, I ticked some people off. That's what a rant will do, Now I've calmed down (and hopefully you have too) and I can try to make myself (And Wilber T Fanning) more well-understood.

Here's what Wilber said last time:
  1. When *everything* stands out, nothing does.
  2. Every function is not a stand-out function.
  3. Every line is not a stand-out line, nor is it a paragraph.
  4. Comments already have a prefix (//, /*, #). That's enough "stand out" for a line that doesn't do anything.
  5. Whatever readability you gain by spreading the code vertically, you lose more by making people scroll.

I later added this:


But my post was only about vertical space density. I didn't recommend cramming everything into a confusing mass within the line. And I did recommend keeping your lines short. Sadly, Charles Y thought I was in favor of production code having the maximum "crammage", and I realize that I said nothing to prevent such a misconception. I didn't say "maximum crammage", so it's not really my fault that I'm misunderstood, but I think Charles helped me to realize I can and should describe my thinking more clearly.

So here it is.




I think that this python loop:

for item in theList:
print item


Is superior to this inferior C-ish one:

int i = 0; // A counter variable

// Iterate over the whole loop so you can print each integer
while(i< sizeof(list)/sizeof(int))
{

// Print the item that the iterator points to and increment the counter
printf("%d", list[i++])

}


But wait, the python one is much more dense! Why is the longer version not superior? It has more whitespace, and has comments!
Because whitespace and comments don't fix the fact that the code is ugly.

Let's hang out with the C loop for a minute here:

Mind you, it doesn't help to merely delete the whitespace and comments, but it does help to show how ugly the code is:

int i = 0;
while( i< sizeof(list)/sizeof(int)) {
printf("%d", list[i++]);
}


Admittedly it's not horrible. Actually, I think it reads ever-so-slightly better than the original because I can take it in at a glance and not have to skip over the comment and blank line "speed bumps". But it's still ugly. Part of the nature of the ugliness is that you don't have a single effect per line. I don't like to see multipurpose lines in my code.


int counter = 0;
int listSize = sizeof(list)/sizeof(int);
while( counter < listSize) {
printf("%d", list[counter];
counter++;
}



I have added an explanatory variable to the mix, "listSize". I have broken the increment of the loop counter to a separate line, and I have renamed the counter so that it's more intentional.

Now, the code is still pretty dense. While it has more vertical spread than the second, it still has less that the first even with an explanatory variable and one effect per line. I will accept the increase in vertical space because there is value for the extra space. The blank lines and comments added no value that I can perceive when I compare the first and third versions.

I can still see at a glance that this is too much code for such a simple function. Why should it be six lines long? It's doing almost nothing!

C programmers would not write the loop that way. It's obviously a 'for' loop, not a 'while' loop. Converting to a 'for' loop gives us a chance to reduce the vertical space further, and that's a good thing if it doesn't hurt the code.


int counter;
int arraySize = sizeof(list)/sizeof(int)
for(counter=0; counter< arraySize; counter++)
printf("%d", list[counter]);


Down from 6 lines to 4 lines in one pop. Nice.

I can stop with this one, because it can't get much better in a language like C. The language demands that we have pre-declared variables, and that's 1/2 of the length of the routine! 50% is given to statically-typed language overhead! Clearly there's something dumb about that, right?

So now it is small and dense, but also is idiomatically correct, has a single effect per line, and has real variable names. I don't think that making this 12 lines long by adding comments and vertical whitespace will make it more readable. In fact, I can't comment it now without merely repeating what the code says in English. It doesn't get clearer. Adding a blank line between the variable declarations and the actual work might look better, if that's what you're into:


int counter;
int arraySize = sizeof(list)/sizeof(int)

for(counter=0; counter< arraySize; counter++)
printf("%d", list[counter]);


I could buy the separation between "trivial prep work" and "the real function" there is a real difference in intent, which means a new "paragraph". That vertical space has a reason to be there, and it adds some kind of real value. See, what I can't stand is pointless whitespace. I suggested that you delete all white space and then add blank lines only where they provide value. You remember me saying that?


C++ has slightly better density because I can reduce the routine by one line:

int arraySize = sizeof(list)/sizeof(int)

for(int counter=0; counter< arraySize; counter++)
printf("%d", list[counter]);



Also, I could use an iterator on an STL container and eliminate the integer array altogether, making is more dense yet. But the iterator syntax is ugly, so I leave it as an exercise for the student.

I can show you a more superior version yet:

list.each {|item| puts item}


Why are the python and ruby forms so much smaller and simpler than C? Because they are smarter containers. A python or ruby list knows a lot more about itself than a C array (which is really doesn't know anything much). The python 'iterator' idiom is "external" so that we iterate over the list in iterators (for x in y gets an iterator from y and iterates over it with X until it gets an iteration stopping exception) and so it still takes a bit more "umph" to get a loop written. In Ruby, the list is much smarter and iteration is internal
you pass it an anonymous function to use on each item it encounters. As such, Ruby wins with greater vertical density and (to ruby programmers) more readability, with less syntax in the way. Also, they're smarter languages in that they demand less punctuation from the programmer in general.

If we hide the ugliness in comments and obscure the code by spreading it thinly out over dozens of lines of code, all it does is keep us from taking in the essense of the code quickly.

Readability is very important to me, but dense, readable code is better than sparse readable code, and either is better than unreadable code (be it dense or sparse). The important part is not merely that long code doesn't fit in the editor window, it's the ratio of reading/decoding compared to the relative value of the code. Dead simple code *should* be tiny. I think that every function should be dense and obvious.

So, even staying in C, I think that this:

int i = 0; // A counter variable

// Iterate over the whole loop so you can print each integer
while(i< sizeof(list)/sizeof(int))
{

// Print the item that the iterator points to and increment the counter
printf("%d", list[i++])

}
is stylistically *far* inferior to this:

int counter;
int arraySize = sizeof(list)/sizeof(int)

for(counter=0; counter< arraySize; counter++)
printf("%d", list[counter]);





!commentForm
 Fri, 25 Aug 2006 14:31:25, Daniel, A Conversation
A: Vertical space is bad.
B: I disagree. Boo!
A: Python and Ruby are better than C.
B: I agree. Huzzah!

I smile in agreement on point #2. And add a summing-up to the original post. Thanks for even the small agreements -- Tim Ottinger

 Sat, 26 Aug 2006 10:18:10, Dave Rooney, What's Wrong with *Some* Space?
Tim,

What's wrong with something like this:

int counter;
int arraySize = sizeof(list)/sizeof(int)

for( counter = 0; counter < arraySize; counter++ )
{
printf( "%d", list[ counter ]);
}


It's not bad, and is in fact my old coding standard preference, which I've sense left. I wouldn't complain if it was handed to me Tim Ottinger

If I'm presented with a whackload of code that someone else has written and need to work with it, I really need to have the whitespace and vertical separation in the code in order to be able to "see" the structure better. To me (and I emphasize *me*), the lack of whitespace creates visual noise that I have a great deal of trouble parsing. I know a few other people like that too. I also know some developers who want to see as much on the screen as possible. So, I suspect that it's a function of our personality/temperament/some other aspect of our psychological makeup. What's right for you isn't right for me, and probably vice versa.

What's right for you in this case is exactly what I *used* to like. A guy named Joel Erdwinn told me that my style was silly because it lacked a certain visual cohesiveness and "wasted lines". I didn't get it at the time. He was in his 60s and I in my 20s at the time. Now in my 40s I see that vertical space is too valuable to waste, and is effective when used well.
Tim Ottinger

Having said that, though, I always find that code written using a code formatting standard is at least consistent, and thus easier to read.

Of course. -- Tim Ottinger


 Mon, 28 Aug 2006 11:13:43, ctran, Obsession
As a developer myself, I enjoy learning others' thoughts but I can't stop thinking if this kind of obsession over little things such as whitespace leads to much complexity in our field.

Maybe that's just the type of person we are!

Just some ranting.
 Mon, 28 Aug 2006 19:17:45, Uncle Bob, Obsession over little things.
Actually I think the obsession over little things like white space is an indication that someone is attempting to acquire mastery.

Think of the stages of becoming a master scultor. Initially you are just trying to figure out how to get rough shapes out of the stone. Later you refine your skill towards every greater detail, eventually working out how to get textures and nuances.

For software developers we first try just to get something working. Later we try to figure out modules. Still later we work out classes and functions. Finally we refine our skills at individual lines of code.

Mastery is a never ending process of narrowing focus over broadening scope.