Signal-to-noise ration as a metric of low-level code readability?

I am currently reading through "Effective Perl Programming". Another fine book that I wish my coworkers would read. (And another fine book they are not going to read). The authors not only want you to write effectively, they want you to write concise code that is easy to read for anyone with a bit of Perl experience. For example, there is a piece of advice in there that says "Avoid excessive punctuation": "[...] Excessive puctuation makes programs less readale [...]" Exactly!

But why is code less readable when it's full of parenthesis, e.g.? I think the answer is simply that the puctuation lowers the signal-to-noise ratio. When reading code, you are looking for the signals, the statements that actually do something, the meat, the beef. A corollary of this is that a bit of whitespace here and there will increase your code's signal-to-noise ratio because it will make the beef stand out.

Here's a stupid little example:

$x=foo();
if(defined($x)) {
    bar($y,$x,$z);
}

That's pretty cramped code and whitespace will make it more readable:

$x = $foo();
if ( defined( $x ) ) {
    bar( $y, $x, $z );
}

It's a lot easier to see what is is that needs to be defined here and what the arguments passed to bar() actually are.

Now, assuming this is possible here, let's get rid of the excessive punctuation:

$x = foo;
if ( defined $x ) {
    bar $y, $x, $z;
}

Even better! Readable! You don't have to concentrate too hard to see what is going on here.

All this got me thinking, that at this low level of symbols, code readability should be measurable. If punctuation increases the noise and whitespace increases the signal, it should be easy to come up with a formula here. Let's try that, with those examples:

$x=foo();

Tokens you need to understand: 3 ($x, =, and foo). Amount of whitespace: 0. Punctuation: 2 (the parens).

So that might be a SNR of ( 3 + 0 ) / 2 = 1.5.

$x = $foo();

Tokens: 3, whitespace: 2, puctuation: 2. This gives us ( 3 + 2 ) / 2 = 2.5.

And finally:

$x = foo;

which results in a divide by zero exception! In this rare case, this is exactly what we want.

I wonder whether something like this could be turned into a Perl::Critic policy? Or does is already exist?

PS: What I really don't get about "Effective Perl Programming" is the unexplained insistence to put the lexical file handle variable with three-argument open in parentheses. As in open my ($foo), '<', 'foo.bar'.

3 Comments

Some discussion over on Reddit.

Edward Tufte says that less ink is more clarity.

The trick of avoiding excessive punctuation is one of moderation. Our advice is not to get rid of all punctuation, but to think about the punctuation that you don't need. The Reddit thread misses the boat there because it thinks it can kill the whole thing with an outstanding (but flawed) example.

There's no rule about which punctuation to banish and which to keep. Look at the particular line of code and the lines around it to see what best communicates the intent there.

Now, communication is a tricky thing because it comes in three parts, and you don't control at least one of them. There's what you think, what you say, and what people think you think. That is, you have to write as much for your audience as you do for yourself.

The problem with things like programming style is that people are often playing to the wrong audience. IT might please you to be Perl Critic warning free and Modernly Perly because you want to be in that world and hang out with those sorts of people, but if the people who have to deal with your code don't care about any of those things, you're probably not communicating effectively. Don't follow advice just to be pure. Do what makes sense for the situation. If the people around you have trouble knowing which arguments go with what, use more parentheses. If they don't use less. Don't blindly apply advice from any source, especially if they don't live in your world.

Leave a comment

About confuseAcat

user-pic Random observations that may in some way be related to Perl.