Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Recently, I was developing a set of coding standards for our company. (We're a new team branching out into a new language for the company.)

On my first draft, I set the purpose of our coding standards as improving Readability, Maintainability, Reliability, and Performance. (I ignored writability, portability, cost, compatibility with previous standards, etc.)

One of my goals while writing this document was to push through the idea of simplicity of code. The idea was that there should be only one function call or operation per line. My hope was that this would increase readability. It's an idea that I carried over from our previous language.

However, I've questioned the assumption behind this push:

Does simplicity always improve readability?

Is there a case where writing simpler code decreases readability?

It should be obvious, but by "simpler", I don't mean "easier to write", but less stuff going on per line.

share|improve this question
14  
If the alternative is "clever" code, then yes... –  Oded Dec 5 '11 at 21:40
2  
yes - per Occam's Razor - en.wikipedia.org/wiki/Occam%27s_razor –  aggietech Dec 5 '11 at 21:43
14  
Try to avoid using such rigid terms as always and never. This is to avoid focusing on edge cases and instead focus on the most common issues we face. This is what best practices are all about. –  P.Brian.Mackey Dec 5 '11 at 22:50
    
actually, you want 2 functions/operations per line. a = b is one operation, b + c is a second, which means a = b + c is 2 operations. Chaining 2 functions/operators is still readable: foo(bar()), or a = foo(). –  zzzzBov Dec 6 '11 at 3:41
2  
Also, don't worry too much. If you try to eliminate every bit of subjectivity from your explanations, just like if you try to specify every possible detail of coding style in a million or more rules, your standards will be overcomplex, unreadable, ignored and therefore pointless. –  Steve314 Dec 6 '11 at 8:00
add comment

15 Answers

up vote 37 down vote accepted

"Simple" is an overused word. "Readable" can profitably be defined as "simple to understand", in which case increasing (this measure of) simplicity by definition increases readability, but I don't think this is what you mean. I've written about this elsewhere, but generally something can be called "simpler" either by being more abstract (in which case fewer concepts can express more phenomena) or by being more concrete (in which case a concept does not require as much background knowledge to understand in the first place). I'm arguing that, depending on perspective, a more abstract concept can reasonably be called simpler than a more concrete concept, or vice versa. This, even though "abstract" and "concrete" are antonyms.

I'll use as an example some Haskell code I wrote a while ago. I asked a question on stackoverflow about using the List monad to calculate a counter in which each digit could have a different base. My eventual solution (not knowing much Haskell) looked like:

count :: [Integer] -> [[Integer]]
count [] = [[]]
count (x:xs) =
  -- get all possible sequences for the remaining digits
  let
    remDigits :: [[Integer]]
    remDigits = count xs
  in
  -- pull out a possible sequence for the remaining digits
  do nextDigits <- remDigits
     -- pull out all possible values for the current digit
     y <- [0..x]
     -- record that "current digit" : "remaining digits" is
     -- a valid output.
     return (y:nextDigits)

One of the answers reduced this to:

count = mapM (enumFromTo 0)

Which of these is "simpler" to understand (i.e. more readable) depends entirely on how comfortable the reader has become with (abstract) monadic operations (and, for that matter, point-free code). A reader who's very comfortable with these abstract concepts will prefer to read the (short) more abstract version, while one who is not comfortable with those operations will prefer to read the (long) more concrete version. There is no one answer about which version is more readable that will hold for everybody.

share|improve this answer
11  
Some developers will progress until they understand and prefer the one-liner. Hard to imagine a developer who understands the one-liner coming to prefer the long version. Therefore IMO the one-liner is clearly better. –  kevin cline Dec 5 '11 at 23:00
7  
@kevincline - assuming the developer is working in isolation, I agree, the shorter version is (probably) better. If she's working as part of a team, and the team is not at the level where they understand and prefer the one-liner, and they must all be able to maintain the code, then the long version is (probably) better in that circumstance. –  Aidan Cully Dec 5 '11 at 23:04
6  
As a counterpoint: given that you're an experienced Haskeller, you can read the second version in a glance. The first version, on the other hand, would require reading and understanding significantly more code; you could not do it in a glance. I think that makes the second version simpler. –  Tikhon Jelvis Dec 5 '11 at 23:37
5  
@Steve314: mapM is pretty idiomatic, and enumFromTo does exactly what it says on the tin. In general, I find it's actually easier to make off-by-one errors if you expand code out--there's simply more code to make a mistake in. This is especially evident with things like for loops vs higher-order procedures in other languages, but I find it to be a general principle. –  Tikhon Jelvis Dec 6 '11 at 8:13
1  
@Tikhon - but that doesn't necessarily mean reading that much code, and the code is right there. Meaning there can be a trade-offs. Usually heavily one-sided in favor of using existing functions rather than re-inventing the wheel, but there are exceptions. This gets very obvious in C++, with some of the more trivial "algorithms" in the standard library - using them can occasionally be more verbose and less clear that writing the code directly. –  Steve314 Dec 6 '11 at 8:39
show 11 more comments

If your coding standard is about "Readability, Maintainability, Reliability, and Performance" then just state that.

Don't try and prescribe how to achieve these things as there will always be situations where there is a counter example.

What you do need to prescribe is things that will cause code to break if not adhered too. Stylistic traits will not break code and should be suggestions (as long as a majority of the team agree that it is Readability the rest should be developer preference (with code review so that peer pressure reminds people that other people need to read the code)).

share|improve this answer
    
That was the goal that I aimed for and that was the stated object. Simplicity (or rather, the one function/operation per line) seemed to naturally follow from that goal. I'm trying to ascertain whether my understanding was invalid. When you're building a coding standards, establishing a set of rules and guidelines is the entire point of the exercise. Setting rules and guidelines that are too vague is useless. As such, this answer really doesn't help. –  Richard Dec 5 '11 at 22:29
5  
My argument is that setting rules that are too strict is worse than useless and is actually harmful. Setting rules like one statement per line is stylistic. This is the thing that should definitely NOT be in the code guidelines. It provides not actual benefit and can be harmful to readability and maintainability if applied without thought. –  Loki Astari Dec 5 '11 at 23:41
2  
+1 (because I can't +10) A common mistake I see with new programming managers is that they try to codify every last detail. The best coding standards are more like fortune cookies than recipes. –  JohnFx Dec 6 '11 at 1:33
    
"Coding styles and standards" was the name of the document. Obviously this isn't a standard (as in "Never use GoTo" or "Never use short ints") but a style. Unifying style is important to readability and maintainability. –  Richard Dec 6 '11 at 14:17
1  
Style Guide: "This project uses tabs/spaces (choose one). This project uses the brace style K&R/Allman/BSD/GNU (choose one). Please don't not add empty spaces on the end of lines. Please keep your code neat and readable. Everything will be code reviewed by two team members and yourself: for readability/maintainability you need a majority 2/3 to check in code, For Reliability, and Performance you need 3/3 (Please provide appropriate tests to prove). More rules will be added if these are abused :-)" Done. –  Loki Astari Dec 6 '11 at 16:44
show 1 more comment

Less "stuff per line", simplicity, and readability are not the same thing. One can take an incredibly complicated obscure undocumented algorithm and code it with 1 statement per line instead of 2, and it won't become that much more readable.

Less "stuff per line" also might require supplying developers with great big tall monitors to see code blocks now spread out more vertically. Or cause eye strain from reading tinier fonts.

Readability is it's very own metric, which often requires a compromise among several other more easily measurable metrics. Pre-constrain all those other metrics, and the compromise no longer becomes possible, resulting in less readable code.

share|improve this answer
add comment

Always? - NO

Ironically, attaining the right level of simplicity can be a complex undertaking. I think the key is in moderation. Simplicity can also be in the eye of the beholder, so if you find yourself over-thinking it - just leave it alone or come back to it later.

Personally, when I try to go back and simplify something that I've written I focus on areas where I changed my mind or tried a couple of things to get what I wanted. Those areas can usually be smoothed out. Then just make a couple of passes through the code to make it more readable without spreading things out so much that you're jumping all over the place to figure out what's happening on a debug.

share|improve this answer
add comment

If I go for simplicity, I can write code like this:

10000000000000000000000000000000000000000000

But if I go for readability, I will prefer this:

1e43

On the other hand, 1000 is much more readable and simple than 1e3 unless you work with numbers in scientific notation all the time.

This is a degenerate example of much more general pattern you can find almost anywhere -- building something out of very simple blocks can quickly become unreadable/inefficient/bad in a lot of different ways. Generalizing and reusing, on the other hand, is harder at first ("wtf is e?! did they mean to write 1343?" someone might say), but can help a lot in the long run.

share|improve this answer
    
Your point about "1e3" being less readable than "100" is well put. In fact, this is a great example of how cognitive load influences readability. "1e3" requires reading 3 characters, AND translating the exponentiation. Reading "100" requires reading 3 characters, and no further evaluation. –  Stephen Gross Dec 9 '11 at 16:07
    
Stephen, actually when reading a three-digit number like 100 you have to perform two multiplications and two additions (0+10*(0+10*1)). However, having used to this notation, you don't even notice that. This again shows how subjective the notion of simplicity can be. –  Rotsor Dec 9 '11 at 16:40
    
Interesting. So, strictly speaking, "100" requires 2 multiplication (1 * 100, 0 * 10), and 2 addition operations. "1e3" requires one multiplication operation. So, absent any cognitive context, "100" is harder to read than "1e3". But! If you include context-switching cognitive load, the calculation is different. Since we normally read integers in non-scientific form, "100" is easier. But, if we are writing an engineering app in which all numbers are expressed in scientific notation, the "1e3" form is easier! –  Stephen Gross Dec 9 '11 at 16:58
add comment

Not necessarily. If you've got a complex operation, that complexity has to go somewhere. Reducing the number of "stuff" that goes on one line just means it will take up more lines, which can actually be detrimental to code readability if it makes your routine too "tall" to fit on one screen.

share|improve this answer
    
Complexity is not irreducible. We have "abstraction" and "chunking" and "organization" to try to manage complexity. I would think that a complex operation can be described in a number of simpler steps. It works for many real-world physical processes: summaries, overviews, etc. –  S.Lott Dec 5 '11 at 21:54
1  
@S.Lott: True, but enough scrolling and Ctrl-clicking could make a "simplified" process more difficult to follow. I've seen it happen once or twice (it's not common but it can be very frustrating to work with when it goes too far). –  FrustratedWithFormsDesigner Dec 5 '11 at 21:57
3  
@S.Lott - there are still bounds to how far complexity can be reduced. You can eliminate unnecessary complexity, but you can only manage (not eliminate) necessary complexity - the complexity that is inherent in the requirements. Arguably, the mechanisms to manage complexity also increase complexity - some added complexity is involved in moving irrelevant complexity out of the way to better reveal the relevant details for a particular aspect/issue/construct. –  Steve314 Dec 6 '11 at 7:09
1  
@S.Lott - Well, it's certainly true that you can represent any requirement you want with a zero-complexity (completely empty) source file. But since you need a very specific language to get your requirements fulfilled, all you're doing is moving your requirements into the language specification. –  Steve314 Dec 6 '11 at 11:39
1  
@S.Lott - if you're claiming that you can predict the position of Jupiter on Christmas Day using nothing but G=0, I think you're insane. If you're not, you're missing my point. Certainly you can abstract away irrelevant detail, but it's not irrelevant if your requirements say it's relevant. If you read back, I never claimed that all complexity is necessary - only that some complexity is inherent in the requirements and cannot be eliminated. –  Steve314 Dec 6 '11 at 12:09
show 6 more comments

Does simplicity always improve readability?

No. I have seen plenty of cases where doing multiple simpler things on one line is less complex than having multiple lines.

There is a trade off between less code and simpler code.

In general I would recommend going for simpler code unless your sure doing it in fewer lines is better. I would much rather "too verbose" code over "too complex"

share|improve this answer
add comment

Clarity + Standards + Code Re-use + Good Comments + Good Design could improve readability.

Simplicity is not always in the hand of the developer because the nature of algorithms and the complexity of application structure these days.

Take the simple web pages that perform simple tasks. Given a sort routine, it is not possible to simplify the logic, but you can make it clearer with comments, using meaningful variable names, having it written in a structured manner, etc.

share|improve this answer
add comment

"Make things as simple as possible, but no simpler" - An often paraphrase of Albert Einstein

Simplicity improves everything. For differing values of simplicity, of course. Is it less lines of code? Maybe. Is it a smaller executable? Possibly. Is it something your team needs to agree upon? Absolutely.

share|improve this answer
    
+1 for the quote, but does simplicity improve readability? –  Richard Dec 5 '11 at 22:32
    
"Make things as simple as possible then simplify them" is a better paraphrase as SW engineers are prone to over engineering. –  mattnz Dec 5 '11 at 23:32
1  
I wish people would stop saying "make things as simple as possible, but no simpler". Can't we at least generalize to MakeAsGoodAsPossibleButNoMoreSo<Thing,Attribute> as our go to uselessly general engineering tip? (Sorry @Jesse C. Slicer, you are far from the only person to quote this, so you don't really deserve the mini-rant more than anyone else). –  psr Dec 5 '11 at 23:54
add comment

Does simplicity always improve readability? Yes. Is one statement per line always simpler? No. Quite a few languages have a ternary operator, which, once grasped, is simpler and easier to understand than the equivalent if/else assignments.

In languages that allow multiple variables to be set on one line, doing so is frequently simpler and easir to understand than whatever the equivalent is.

Another example: regular expressions do a lot, typically in just one line, and the equivalent without a regex is frequently much harder to read. /\d{3}[ -]\d{3}-\d{4}/ is the equivalent of a function call with several comments at the least, and is easier to understand than the corresponding function body.

share|improve this answer
add comment

Readability and simplicity are subjective terms which, depending on the person and the context, usually but not always go together.

A more objective term is conciseness - something you could in principle count by counting characters, though there are some flaws in that. Conciseness seems to imply simplicity and readability, but there are (at least in my opinion) exceptions.

A longer (and arguably more complex) piece of code can be more readable if it better expresses intent. Whether your definition of simplicity cares about intent is another subjective thing - you could define complexity in terms of the syntactic structure and information-theory entropy, for instance, with no reference to intentions at all.

So, a well-chosen longer variable name may...

  • Improve readability by better expressing intent
  • Reduce conciseness - it is longer, after all
  • Have no effect on syntactic simplicity at all - the syntactic structure of the code is unchanged

Similarly, I might write if (some_boolean == true). In comparison with the equivalent alternative if (some_boolean), this...

  • Reduces conciseness
  • Reduces syntactic simplicity, but
  • May improve readability by better expressing intent.

Of course this one will trigger a mass protest - to plenty of people, this always damages readability too. To me, it depends a lot on the source of the boolean - e.g. the variable name (or method name or whatever) may not clearly express that the value is "truth value". Sure, the if tells you something, but it still smells. But plenty of people will call me an idiot for believing this.

Which is further evidence of the overall subjectivity, of course.

share|improve this answer
add comment

Always? - YES

Attaining the right level of simplicity is a complex and difficult undertaking. But always worthwhile since it always improves readability. I think the key is deep understanding. Simplicity is an absolute, measured by "new concepts" per "chunk" of code. A few new concepts means simpler.

Focus on areas where there are a dense cluster of concepts and find ways to "chunk" or "summarize" or "abstract". Make a couple of passes through the code to make it simpler and more readable.

A good abstraction is worth it's weight in gold. A good abstraction makes this simpler -- and consequently more readable.

share|improve this answer
    
I can't help thinking that your scare-quotes are there because you're aware that "concept" and "chunk" are themselves subjective. One persons single concept is another persons amalgam of three distinct ideas. It's hard to have an absolute and objective measure of subjective stuff. –  Steve314 Dec 6 '11 at 8:12
    
@Steve314: Scare quotes? No. en.wikipedia.org/wiki/Chunking all seem to be similar in that they describe simplification through chunking. (Except the guitar technique, that seems different.) The quotes are there because there are so many alternate terms for abstraction, chunking, summarizing, etc. If I pick just one everyone objects that abstraction isn't the same thing as chunking. The quotes are there to emphasize that this is somehow debatable. Yet. It's clearly done all the time and seems to be a natural human tendency. –  S.Lott Dec 6 '11 at 10:54
    
What I don't deny - chunking is done all the time and is a good idea. What I deny - that there's a definitive objective rule for where the boundaries should be between chunks. My arguments may be more pedantic than helpful, but I still doubt the "always" in "always improves readability". –  Steve314 Dec 6 '11 at 11:27
    
@Steve314: We always abstract, chunk and summarize to help ourselves understand things. Always. Chunking, abstracting, summarizing ("simplifying") is something we always do. We just do. It's how our brains apprehend reality. Simplification always improves readability, and can always be done. –  S.Lott Dec 6 '11 at 11:39
    
yes, we do. I never said otherwise. –  Steve314 Dec 6 '11 at 11:56
show 9 more comments

You're all missing some fundamental definitions. Simple, from the root sim-plex, means one fold. Simple means doing one thing. Easy, from the root ease, means lie near. Easy means that it is close at hand. The examples of simple code given in other answers aren't exactly what they appear.

Take rotsor's display of a very large value. He says this is simple. Is not, in my estimation, simple. It's easy. It's close at hand to type the number of required 0s.

10000000000000000000000000000000000000000000

The readable version is simple. It does one thing. It expresses the number by describing its size in a notation purpose built for this function.

1e43

Could you describe Aidan's "simple" code snippet as doing one thing? It contains 10 lines of code (not counting comments) and at least 7 blocks (as I'd count them). If you follow the comments, you'd see that it does at least 4 things!

count :: [Integer] -> [[Integer]]
count [] = [[]]
count (x:xs) =
  -- get all possible sequences for the remaining digits
  let
    remDigits :: [[Integer]]
    remDigits = count xs
  in
  -- pull out a possible sequence for the remaining digits
  do nextDigits <- remDigits
     -- pull out all possible values for the current digit
     y <- [0..x]
     -- record that "current digit" : "remaining digits" is
     -- a valid output.
     return (y:nextDigits)

But, one of the recommendations for rewriting this code was one statement. Aidan does state that a reader would have to be or become familiar with monadic statements, pointer free code, etc. That's fine. Those concepts are singular and independent to learn.

count = mapM (enumFromTo 0)

You'll find that truly simple code is more readable than easy code because it does only one thing. You may need to go off and learn more "one things" to understand the simple code. But it should always be more readable.

share|improve this answer
add comment

The questions reminds me of this answer on Stack Overflow, particularly this quote (substitute quality with simplicity):

Quality -- you know what it is, yet you don't know what it is. But that's self- contradictory. But some things are better than others, that is, they have more quality. But when you try to say what the quality is, apart from the things that have it, it all goes poof! There's nothing to talk about. But if you can't say what Quality is, how do you know what it is, or how do you know that it even exists? If no one knows what it is, then for all practical purposes it doesn't exist at all. But for all practical purposes it really does exist. What else are the grades based on? Why else would people pay fortunes for some things and throw others in the trash pile? Obviously some things are better than others -- but what's the ``betterness''? -- So round and round you go, spinning mental wheels and nowhere finding anyplace to get traction. What the hell is Quality? What is it?

I think that it's important that you keep in mind that a codified coding standard for all its benefits will not make good programmers out of bad ones. A word like 'simple' may be interpreted differently by different people (see Aidan Cully's answer), but that may not be such a bad thing. Junior programmers will still need to have their code reviewed by senior programmers and learn why the senior programmers interpretation of 'simple' is better than their own.

share|improve this answer
1  
This is why I defined simplicity in the question. –  Richard Dec 6 '11 at 14:23
add comment

One function call per line is simpler? Let's try an example!

=== One call per line ===
x = y.getThis()
a = x.getThat()
b = a.getSomethingElse()

=== Less "simple" version ===
b = y.getThis().getThat().getSomethingElse()

What do you think? Is one call per line actually simpler?

share|improve this answer
    
Yes. One call per line is simpler and easier for me to read. However, readability is subjective. (Also, this doesn't even come close to answering the question.) –  Richard Dec 12 '11 at 13:26
    
Hi Stephen, can you elaborate on how you think this answers the question? It's not clear what you you're trying to point out here. –  user8 Dec 12 '11 at 17:44
    
@MarkTrapp No problem. The original question proposed a single-function-per-line approach. The example I posted shows the same two code snippets, one implemented as single-function-per-line, the other as chained-method-calls. I think the chained call is a lot easier to read: short, devoid of unnecessary temporary variables, and elegant. –  Stephen Gross Dec 12 '11 at 19:37
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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