This site will look much better in a browser that supports web standards, but is accessible to any browser or Internet device.

Anomaly ~ G. Wade Johnson Anomaly Home G. Wade Home

July 28, 2013

Coding Style: Terse vs Verbose, Conclusion

In the last post (Coding Style: Terse vs Verbose), I laid out some of the arguments for and against a verbose coding style and a terse coding style. Although, I didn't delve deeply into what I meant by these styles, I hoped the details were less important than the general feel.

However, by the end of the post, I had not answered the one very important question.

Which Way is Best?

Like most decisions in programming, this one involves trade-offs. The key to the answer is in a previous entry (Write for Your Audience). Odds are, neither of the two extremes is the right way. Depending on the programmers writing and maintaining your code, the team will need to make different decisions.

Team Makeup

If your programmers are all new to the language and the program and always will be, write as verbose as you can. An example of this would be a program written and maintained by a stream of interns or short term employees. If the skill level of the maintainers never progresses, they need to keep things obvious.

Another case where the verbose style is helpful is a system maintained by one or more non-programmers as a side project. In this case, the extra verbosity will help them get oriented when they come into the code. Since they are not intending to become experienced programmers, they have less incentive to become well-versed in the intricacies of the language.

If, on the other hand, your code is maintained by experienced programmers that are working on this system as their primary jobs, a terser style is probably more efficient. Although it may make life a bit harder for new developers coming in, no one is the new guy forever. If a terser style is more readable to most of your programmers over most of the time that they work on the project, you are better off adopting that style.

In any case, the style should fit the audience that will read and maintain the code.

Trade-offs

Almost every interesting problem in programming has trade-offs. There is no one, true answer.

If your experts will read your code much more often than novices, feel free to allow a more terse style. If people with less experience will read the code, making it somewhat more verbose may be the right choice.

It is probably not wise to make any of the code too terse or too verbose. You want people to be able to become experts eventually, so the learning curve can't be too steep. Likewise, you don't want code that is so verbose that it ends up dumbed down to the point that no one wants to work on it.

Most of your code will be maintained by people between the two extremes, so the verbosity level of the code will also need to be between the extremes.

An approach that I have found to be useful is to find a style that most of your team is somewhat comfortable with. The really junior people will find it a little terse. Your senior people will see it as a little verbose. That should be the goal for most of the code. Where necessary, your team can write really performance critical or seriously advanced code more tersely than this standard. Only experienced people will work on it anyway. Your team should write any code that is likely to be read outside the core programming team more verbosely than the standard.

The resulting style will not be consistent across the whole code base. But, it will be more comfortable for the people who work in each area.

Myths

One of the most important points to realize is that either extreme is bad. Since this is a polarizing issue, each side quotes myths about either style that support their own argument.

If a little verbosity makes the code more readable to new people, more verbosity must make it even more readable, obviously.

For an example of extreme verbosity, we could have code that takes 100 lines (taking into account comments and such) to increment a single variable. This is obviously not better than a terser version. Depending on the code, one line or a couple of lines might be a little verbose, but perfectly clear.

For any given audience, there is a sweet spot between maximum terseness and maximum verbosity that generates the best clarity. This spot is very hard to find and maintain. I've worked with a number of people that think it is better to err on the side of verbosity. By itself, that is not unreasonable.

However, if you keep going in that direction, you quickly reach a point where everyone has to wade through huge amounts of extraneous stuff to understand the code. At this point, your experts are no more effective than a random developer walking in off the street. Unfortunately, this kind of least common denominator code seems to chase off good developers.

Succinct code is more cryptic and harder to understand.

Succinct code, by its nature, relies on other context for clarification. Opponents of a terse style will sometimes point to a single line or statement and declare that it is unreadable. The fallacy is that you almost never look at only one line of code. This would be like taking the single sentence "She was confused when he did that" from of a story and declaring this as proof that pronouns make English unreadable. The rest of the story (or maybe just the page or paragraph) would make she, he and that perfectly clear.

Using an overly verbose style can be a lot like trying to write or speak without using any pronouns, contractions, or idioms of any kind.

Sometimes, the supposed cryptic code is just using a specialized vocabulary. Someone unfamiliar with that vocabulary will find it hard to understand until they learn the terminology.

Verbose code obscures the really necessary parts, making the code harder to understand

While extremely verbose code can make finding the important bits difficult. Sometimes a small increase in verbosity can increase clarity for less knowledgeable developers, without a major impact on the expert developers. A good example is careful naming of variables and functions. The variable speed_of_sound is likely to be easier to follow than SoS.

Verbose code is more debuggable

Many people believe that the only way to troubleshoot a problem is to run it through a debugger. For those people, verbose code can be better because it gives more possibilities for breakpoints. For example, we could always use very simple named sub-expressions, instead of long mathematical equations. That way we could print individual pieces or single-step through a calculation carefully.

Let's look at some code in C.


    float first_solution( float first_coefficient, float second_coefficient, float third_coefficient )
    {
          float square_of_second = second_coefficient ** 2;
          float product_first_third = 4 * first_coefficient * third_coefficient;
          float double_first = 2 * first_coefficient;
          float major_term = sqrt( square_of_second - product_first_third );
          float numerator = - second_coefficient + major_term;
          return numerator / double_first;
    }

It definitely has many pieces that can be checked independently. There are many places for breakpoints. But, the overall structure of the code is pretty obtuse. Compare with the following example, that carries the context from when you learned the quadratic equation sometime in the past.


    float first_solution( float a, float b, float c )
    {
          return (-b + sqrt( b**2 - 4*a*c )) / (2 * a);
    }

It's pretty easy to verify this equation against your memory or a math textbook. There's really no need to debug it. At a glance, I'd say the biggest problem I can see with the second form is the use of floats instead of doubles. This gives a potential for lose of necessary precision in some cases. The same problem applies to the other code, but is not as obvious. Instead you are drowning in lots of text and this issue becomes harder to see.

In this case, the succinct code is clearer because we are familiar with the formula. Just as importantly, despite the extremely short parameters names, it is still readable because of the context of the standard representation of this formula.

Correct is more important than debuggable.

It's a fairly reasonable argument that if the code is actually correct, there is no reason to ever debug it. Unfortunately, that relies on a rather large if. How do you know that the code is correct? More importantly, 3 years from now when the environment where this code is running has become completely different, is the code still correct? And how would you know?

Some of the most interesting bugs I've seen in my career have been in code that was obviously correct.

Verbose code generates more lines of code, so it can't be correct.

The bugs per lines of code argument is an interesting one. The most often quoted form of this is from Steve McConnell's book Code Complete, Second Edition.

Industry average experience is about 1-25 errors per 1000 lines of code for delivered software.

Later in the book, McConnell shows that this defect rate increases as the code base gets bigger.

Unfortunately, this myth is based on a really important logical mistake. As an example, if I took a working 10 line program and added 10,000 copies of the line x=x; (assuming x is available), would that automatically imply that the code has acquired 10-250 defects? The only real effect would be potential performance impact, unless you are using a modern compiler which would optimize this code away.

This does not mean that adding code won't increase the number of bugs. We just can't say there will be more bugs simply because there are more lines of code.

Verbose code will reduce the learning curve for new programmers.

This myth rests on two assumptions.The first assumption is that verbose code is necessarily clearer than a more concise version. As we saw in the quadratic equation example above, that may not be true. The other assumption is that we actually care to make things easier for the new programmer.

If a programmer is on a particular project or with a company for 5 years (as an example), and they are effectively new for 6 months, that means that we get a benefit from the verbosity for 10% of the career of that programmer in this code. Any downsides of the extra verbosity will effect the remaining 90% of that programmers career in the code. More importantly, it will impact 100% of the time of any senior developers in the code.

In my experience, the more senior people are often quite a bit more productive than the junior people. (Any junior people who are more productive, usually don't remain junior for long.)

In summary, more verbose code may not actually be clearer. At best, will only help some of your people for a short while. If there is any downside at all with more verbose code with respect to your more senior people, it sounds like a bad trade-off.

We only hire the top 5%, they will be able to understand our style.

Everybody says this. By definition, most companies cannot be hiring just the top 5%. Since, by definition, most companies are paying average salaries, have average benefits, and are working on average problems, the top 5% probably aren't even applying to your company. Most of your programmers are probably around the average for your area.

So, writing overly terse code intentionally, because you employ the best of the best, may not be the best strategy.

The code has to be this cryptic for performance reasons.

One real cause of cryptic code is micro-optimizations for performance. While micro-optimizations can improve performance in some cases, they almost always make the code more difficult to read. Unfortunately, programmers are truly awful at recognizing performance bottlenecks without careful profiling. In many cases, the optimized code was just not performance critical, in the first place. This problem is known throughout the field as premature optimization.

It's usually better to write code clearly until you have actual numbers proving that the code is a performance problem. Even then, exploring better algorithms, written clearly may be a better use of time.

Since this code isn't performance-critical, we can make it more verbose without penalty.

In the book C++ Coding Standards, this is referred to as premature pessimization. We can think about this problem by using the rule that 20% of the code controls 80% of the performance. So we can make the most benefit by performance tuning that 20%. But, if we make the other 80% of the code consistently slower it will still affect 20% of the performance, which can add up.

In one system I worked on, I saw a new piece of code that was written in a sub-optimal fashion (O(n3) to be exact). When I suggested we rewrite the code more efficiently, I was told this wasn't a performance critical piece of code and n would never get very big anyway. A couple of weeks later, I was asked for help because the system was way too slow. This pessimized code turned out to be the problem.

Conclusion

The verbosity of your coding style is another facet of the know your audience issue. Rather than aiming only for verbose or terse code, you should focus on the right style for the audience of that code.

As usual, there is no simple, obvious, correct answer. The style of your code is a complex issue that depends heavily on who will see the code.

References

Posted by GWade at July 28, 2013 12:46 PM. Email comments
G. Wade Johnson is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to amazon.com.