Are there cases where more verbose code (as in more logical statements) is more clean than more concise code?

closed as too broad by gnat, Bart van Ingen Schenau, Pieter B, maple_shaft Oct 12 at 15:46

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
  • 18
    Of course it does. Even when eliminating duplication, the code to define the new extracted function takes up space of its own. Writing a new function may take four lines and save only two, and still be a worthwhile thing to do. – Kilian Foth Oct 12 at 6:19
  • 5
    "more concise code"? I really hate the misguided belief that a smaller line count means "better" code. It doesn't. In fact, it's usually the opposite. There comes a point - and it's reached really fast - where cramming more and more meaning into less and less space makes code harder to understand. In fact, there's an entire competition - The International Obfuscated C Code Contest - where many winners rely on those limits of human comprehension to write impenetrable code. – Andrew Henle Oct 12 at 11:05
  • 1
    The title of your question and your question itself are asking different questions. For example, an if statement can be changed into a ternary expression which is the same logically but only 1 line. – Captain Man Oct 12 at 13:01
  • 1
    -1 ***more verbose code (as in more logical statements) *** verbosity and the number of logical statements are two unrelated things. It's bad form to change definitions. – Pieter B Oct 12 at 13:31

To answer that, let's take a real world example that happened to me. In C# a library that I maintain, I had the following code:

TResult IConsFuncMatcher<T, TResult>.Result() =>
    TryCons(_enumerator) is var simpleMatchData && !simpleMatchData.head.HasValue
        ? _emptyValue.supplied
            ? _emptyValue.value
            : throw new NoMatchException("No empty clause supplied");
        : _recursiveConsTests.Any() 
            ? CalculateRecursiveResult() 
            : CalculateSimpleResult(simpleMatchData);

Discussing this with peers, the unanimous verdict was that the nested ternary expressions, coupled with the "clever" use of is var resulted in terse, but difficult to read code.

So I refactored it to:

TResult IConsFuncMatcher<T, TResult>.Result()
{
    var simpleMatchData = TryCons(_enumerator);

    if (!simpleMatchData.head.HasValue)
    {
        return _emptyValue.supplied
            ? _emptyValue.value
            : throw new NoMatchException("No empty clause supplied");
    }

    return _recursiveConsTests.Any() 
        ? CalculateRecursiveResult() 
        : CalculateSimpleResult(simpleMatchData);
}

The original version contained just one compound expression with an implicit return. The new version now contains an explicit variable declaration, an if statement and two explicit returns. It contains more statements and more lines of code. Yet everyone I consulted considered it easier to read and reason, which are key aspects of "clean code".

So the answer to your question is an emphatic "yes", more verbose can be cleaner than concise code and is thus a valid refactoring.

  • 34
    In this day and age, developer's brains are a scarcer resource than disk, CPU, RAM, or network bandwidth. Those other things are important, and in certain applications they might be your limiting factor, but in most cases, you want to optimise for your developers' ability to understand the code first, and then those other things. – anaximander Oct 12 at 8:33
  • 2
    @anaximander, Absolutely agree. Write code for other people to read first and the compiler second. Which is why I find it useful to have others peer review my code, even if I'm the only one developing it. – David Arno Oct 12 at 8:36
  • 4
    If I were reviewing that, I would suggest reversing the order of the return statements and removing the ! from the condition. I would also suggest putting the second return in an else. But even as it stands, it is a massive improvement. – Martin Bonner Oct 12 at 9:10
  • 2
    @DavidArno I see that logic, and if if (!foo.HasValue) is an idiom in your code, even more strongly so. However the if isn't really an exit-early - it's a "do this or that depending." – Martin Bonner Oct 12 at 9:45
  • 2
    @fabric Comparison of boolean values is dangerous. I avoid it as much as I can. – Martin Bonner Oct 13 at 7:13

1. Lack of correlation between LOC and code quality.

The goal of refactoring is to improve the quality of a piece of code.

LOC is a very basic metric which, sometimes, correlates with the quality of a piece of code: for instance, a method with a few thousands of LOC is likely to have quality issues. It should be noted, however, that LOC is not the only metric, and in many cases lacks the correlation with the quality. For instance, a 4 LOC method is not necessarily more readable or more maintainable than a 6 LOC method.

2. Some refactoring techniques consist of adding LOCs.

If you take a list of refactoring techniques, you can easily spot the ones which consist in intentionnally adding LOCs. Examples:

Both are very useful refactoring techniques, and their effect on the LOC is completely irrelevant when considering whether to use them or not.

Avoid using LOC.

LOC is a dangerous metric. It is very easy to measure, and is very difficult to interpret correctly.

Until you become familiar with the techniques of measurement of code quality, consider avoiding measuring LOC in the first place. Most of the time, you won't get anything relevant, and there would be cases where it will mislead you into decreasing the quality of your code.

  • You refactored your answer and improved the quality by adding more LOT (lines of text) :p – grinch Oct 12 at 15:11

If you want to see the ultimate result of just minimising the byte count or LoC count of your source code, go have a look at the submissions to the Stack Exchange Code Golf site.

If your source code is reduced in such a fashion, you'll soon have an unmaintainable mess. Even if you're the person who wrote such code, and understand it fully at the time, how efficient will you be when you return to it in six months time? There is no evidence that such minimal code actually executes any quicker either.

Code should be written in such a manner that any member of your team can look at it, and understand what it's doing straight away.

  • Maybe redundant, but just to spell it out; if you refactor golfed code for readability you always end up with more LoC – JollyJoker Oct 12 at 11:56

Yes refactoring can definitely result in more lines of code.

The most common case IMO is when you take code that is not generic and you make it more generic/flexible. Genericizing code easily makes the lines of code increase significantly (sometimes by a factor of two or more).

If you expect the newly generic code to be used by others (instead of just as an internal software component) as a library then you usually end up adding unittest code and in-code documentation markup which will increase the lines of code again.

For example, here's a very common scenario that happens for every software developer:

  • your product needs an urgent high-priority new feature or bug fix or enhancement in two-weeks (or whatever time-frame is considered urgent for your project-size/company-size/etc)
  • you work hard and deliver XYZ on-time and it works. Congratulations! Great job!
  • While you were developing XYZ your existing code design/implementation didn't really support XYZ but you were able to shim XYZ into the codebase
  • the problem is that the shim is ugly and has terrible code-smell because you did some tricky/clever/ugly/bad-practice-but-kinda-works things
  • when you find time later you refactor the code which may change many of the classes or add a new layer of classes and your new solution is "done right" and doesn't have the bad code-smell anymore... however doing it the "right way" now takes up way more lines of code.

Some concrete examples that come to me off the top of my head:

  • for a command line interface you could have 5000 lines of if/else-if code or you could use callbacks... each callback would be much much smaller and easier to read/test/verify/debug/etc but if you count lines of code the ugly 5000 lines of if/else-if code would probably be smaller
  • for a processing piece of code that supports N methods of processing, you could again use if/else statements which would look the most ugly...
    • or you could switch to callbacks which would be nicer/better but callbacks take more lines of code (still compile time though)
    • or you could abstract further and do plugins that can be changed at runtime. plugins are nice because you don't have to recompile the main product for each new plugin or modification to an existing plugin. and you can publish the API so others can extend the product. BUT again a plugin-approach uses more lines of code.
  • for a GUI you create a great new widget
    • you or a coworker notes that the new widget would be great for XYZ and ABC but right now the widget is tightly-integrated only to work for XYZ
    • you refactor the widget to work for both but now the total lines of code increases

Not the answer you're looking for? Browse other questions tagged or ask your own question.