Is a coding style principle - e.g. the single-exit principle - really a good thing? Always, or just sometimes? How much difference does it really make?

Whatever your opinions, these are obviously subjective questions. Or are they?

Has anyone attempted to make an objective, scientifically rigorous study of coding style principles?

I can't imagine how anyone would do a double-blind study of readability, but maybe double-ignorant might be possible - use students who don't know about the principle being studied as subjects, and non-programmers to administer the study.

  • 5
    You may be intersted in reading code complete. Everything isn't mesureable, but a lot is, and you'll find a good overview with raw data or sources in this book.
    – deadalnix
    Oct 6 '11 at 11:38
  • It also highly dependant on language some principles apply to specific languages an not others. For example the single-exit principle does not really apply to C++ because of RAII Oct 6 '11 at 14:44
  • @Loki - I had to think about that, and I'm not sure I agree. It's true that RAII is designed in large part to cope with exceptions, which are alternative exit points, but (at least to some people) they count as alternative alternative exit points - not really counting against the single exit principle in the way that break, goto or return do. IOW single exit isn't an absolute in C++, but that's pretty much my view of it in C and most other languages anyway. But it's still relevant in a non-strict sense.
    – user8709
    Oct 7 '11 at 5:37
  • 1
    @Steve314, the article is at least distantly relevant - it outlines a design for a methodology of such an experiment, which is quite important due to an obvious lack of properly recorded experimental evidence in this area.
    – SK-logic
    Oct 7 '11 at 6:09

I'm echoing deadalnix's comment: read Code Complete 2. The author (Steve McConnell) discusses coding style in depth and frequently references of papers and data.

  • Fundamental and well presented overview of professional software development, hope one day I'll find similar one for quality assurance. Chapters about Defensive Programming and Pseudocode Programming were especially helpful to me. Chapter on Collaborative Development Practices seems to be most compelling of all I've read on these matters so far.
    – gnat
    Oct 6 '11 at 16:11
  • I've not read this book, and maybe I should, but - based on the comments in gnats answer - are thoses referenced papers really scientifically rigorous and objective? If the answer is "as much as they can be", what compromises were necessary? As I suggested in the question, was it necessary to replace double-blind with some weaker standard?
    – user8709
    Oct 7 '11 at 5:25
  • @Steve314: I don't know, I haven't checked the sources! But you don't always need scientific rigor to establish best practice. A discussion of the pros and cons is sometimes sufficient. Oct 7 '11 at 12:21
  • @emddudley - absolutely true, but not really what this question was about.
    – user8709
    Oct 7 '11 at 12:33
  • @Steve314: Code Complete would be a great starting point for you, and I'm confident that some of its references address the issue of scientific analysis of coding style. Oct 7 '11 at 12:36

I heavily doubt the very possibility of a study on the subject yielding objective results and I will remain sceptical until I am shown some convincing research.

Programmers who've spent years reading and writing code that followed certain coding style will obviously find it more readable than some perfect coding style they would see for the first time in their lifes.

It's exactly the same with the most common QWERTY typing layout - it's easy to prove that it's quite suboptimal in terms of ergonomy (do you think that all the characters of the word TYPEWRITER were put in the top row with our daily convenience in mind?).

But improved alternatives such as Dvorak or Colemak have never caught on and are unlikely to. And therefore people are not more productive with them - fact. Even if they're superior in some abstract sense.

Also, it would be difficult to find subjects with no prior exposure to programming (as this would contaminate the result of our study), BUT an aptitude for programming, AND the will to participate in a study for a period long enough to show both short-time benefits and long-time benefits so that they could be weighted against eachother... (I don't know whether they're mutually exclusive, but the researchers could not simply assume they never are).

  • 1
    Cool, I had never heard of Colemak before
    – CaffGeek
    Oct 6 '11 at 13:35
  • 1
    @Chad even less known is Carpal X, which I toyed with for a while. I found it nicer than Colemak (I reached 90-100 wpm with carpalx). Even if you don't intend switching to any exotic layouts, the carpalx website makes an extremely interesting read on evaluating and optimizing keyboard layouts, and utilizing genetic algorithms for this category of problems. See mkweb.bcgsc.ca/carpalx Oct 6 '11 at 13:40
  • 1
    Sometimes the marginal benefits of an alternative approach will be great enough to justify the cost of adopting it; otherwise we'd all still be programming assembler and fortran. This answer doesn't really respond to the original question on whether or not there are in fact marginal benefits. In the Dvorak example, there certainly are and its been proven, but they are not great enough benefits to justify learning Dvorak.
    – Jeremy
    Oct 6 '11 at 14:53
  • @Jeremy "this answer doesn't really respond to the original question on whether or not there are in fact marginal benefits" - the OP did not directly ask for findings of such studies, he asked whether anyone has attempted to carry such studies out, which is more open a question. I answered by pointing out a couple of logical reasons on why it would be technically difficult, and why any results of such a study would probably be significantly contaminated by statistical noise. So if my answer was deemed as not useful on the grounds you have given, I think I was downvoted unfairly. Oct 6 '11 at 15:10
  • 1
    @Jeremy the gist of these adoption costs is that people perform better with an inferior tool as long as they have had more practice with it. And this is exactly what would show up in any study attempting to examine how well its subjects cope with different coding styles. The noise caused by their prior familiarity/unfamiliarity with coding styles you would have them use would dwarf the impact of any innate qualities of these styles. Unless you leveled the playground by taking up complete beginners. But this poses a practical difficulty, as I pointed out in the last paragraph of my answer. Oct 6 '11 at 15:41

The answer is a definitive NO! Are `break` and `continue` bad programming practices? is a subset of this question, so I'm going to start with a barely modified answer to that...

You can [re]write programs without break statements (or returns from the middle of loops, which do the same thing). But in doing so you may have to introduce additional variables and/or code duplication both of which typically make the program harder to understand. Pascal (the late 1960's programming language) was very bad especially for beginner programmers for that reason.

There's a computer science result called the Kosaraju's hierarchy of control structures, which dates back to 1973 and which is mentioned in Knuth's (more) famous paper Structured programming with go to statements from 1974. What S. Rao Kosaraju proved in 1973 is that it's not possible to rewrite all programs that have multi-level breaks of depth n into programs with break depth less than n without introducing extra variables. But let's say that's just a purely theoretical result. (Just add a few extra variables?! Surely you can do that to feel ingroup with the 3K+ users on stackexchange...)

What's far more important from a software engineering perspective is a more recent, 1995 paper by Eric S. Roberts titled Loop Exits and Structured Programming: Reopening the Debate (doi:10.1145/199688.199815). Roberts summarizes several empirical studies conducted by others before him. For example, when a group of CS101-type students were asked to write code for a function implementing a sequential search in an array, the author of the study said the following about those students who used a break/return to exit the from the sequential search loop right when the element was found:

I have yet to find a single person who attempted a program using [this style] who produced an incorrect solution.

Roberts also says that:

Students who attempted to solve the problem without using an explicit return from the for loop fared much less well: only seven of the 42 students attempting this strategy managed to generate correct solutions. That figure represents a success rate of less than 20%.

Yes, you may be more experienced than CS101 students, but without using the break statement (or equivalently return/goto from the middle of loops), eventually you'll write code that while nominally being nicely structured is hairy enough in terms of extra logic variables and code duplication that someone, probably yourself, will put logic bugs in it while trying to follow some passe idea of "correct" coding style.

And there is one larger issue here besides return/break-type statements, so this question is a bit broader than the one about breaks. Exception handling mechanisms are also violating the single-exit point paradigm according to some

So basically anyone who argued above that the singe-exit principle is still useful today is also arguing against the exception handling paradigm, unless used in the extremely constrictive way described in that last link; those guidelines basically constrain all exceptions out of a function to throw(), i.e. no inter-function exceptions propagation is allowed at all. Enjoy your new Pascal with C++-like syntax.

I see from Where did the notion of "one return only" come from? that the prevalent opinion on this site is to the contrary of what I posted here, so I fully understand why I've been down-voted already, even though I'm the first answer here to actually provide something that the question asked for: some info on actual usability tests focused on the single-exit issue. I guess I shouldn't let knowledge get in the way of preconceptions, especially on a gamification site. I'm going to stick to editing Wikipedia from now on. At least there info from good sources is appreciated and vague or incorrect claims pretending to be backed by sources eventually earn a ban. On this site, quite the opposite happens: opinions unsubstantiated by facts dominate. I full expect a mod to delete this last part, but at least that dude will know why you've lost me forever as a contributor here.

  • I didn't downvote this, but on your "But in doing so you may have to introduce additional variables and/or code duplication both of which typically make the program harder to understand." point, that's a subjective claim. I agree that adding a variable or code duplication makes it hard to understand, but arguably adding a goto makes it hard to understand too, plus arguably the damage done by duplication can be mitigated by factoring the duplicated code out into a function (though IMO moving complexity into the call graph doesn't automatically eliminate it).
    – user8709
    Jul 17 '14 at 23:10
  • I saw your point about the 1995 paper only after that last comment, and decided to upvote - interesting point. I think your downvote may be more because your post is long, and starts out with a subjective point, so probably the downvoter didn't read the whole thing (the same as me, at first). Basically, it's a good idea to introduce your real point early.
    – user8709
    Jul 17 '14 at 23:19
  • Anyway, I think a lot of people think of exceptions as kind of alternative alternative exit points - because they're meant for error cases (sort of) they don't really count. I understand that's a bit language-culture sensitive, though. In some languages "exception" is more than the name - an exceptional success case is valid (and IIRC Stroustrup said something like that about C++, raising a philosophical point about whether an error is an error if it's handled). Some even say exceptions are just another control flow to use whenever it gives the control flow you need.
    – user8709
    Jul 17 '14 at 23:23
  • 1
    @Steve314 "plus arguably the damage done by duplication can be mitigated by factoring the duplicated code out into a function" Putting out of line and out of immediate view part of a logic of the function, a part that makes no sense isolated. Making it even harder to understand the logic of the function.
    – curiousguy
    Jun 29 '18 at 21:02
  • 1
    @curiousguy - yes, that's true, and probably part of the intent of my "moving complexity into the call graph" point. My religion is that every choice you make is a trade-off so be aware of all plausible options and their advantages and disadvantages, and knowing the common mitigations is important but beware in case the cure is worse than the disease. Except of course that part of the trade-off is how much time you spend (or waste) fussing about things.
    – user8709
    Jun 30 '18 at 15:42




[Your questions seems to be answered by a single word, "yes". I have been told, however, that providing short answers is "dismissive" of the question. If you feel I've been dismissive, please flag the answer so a moderator can delete it.]

  • 1
    @luis.espinal: Toward what end? What information would the text contain? The question rambles around a bit. What part of the question should be addressed with some text?
    – S.Lott
    Oct 6 '11 at 14:51
  • 1
    As a matter of style, and perhaps to provide more information that the links' abstracts can provide (considering that we don't know if the OP is a paying ACM/IEEE/Springer Verlag member with access to the full articles and find answers to his questions.) For example, the ACM article abstract makes no mention of coding style. At most it talks about corroborating the structured program theorem (which itself does not talk about the single or multiple return problem). So you could have explained why that link is relevant. Oct 6 '11 at 15:46
  • 1
    Third article (thankfully I do have access to IEEE Xplore) doesn't seem related to what the OP is asking as far as I can tell. It is a wonderful article mind you, one which I'm printing for more dedicated reading at a later time. So maybe you could also have explained how this article helps the OP answer his question. Overall, it seems you simply threw a bunch of links together. It is not a manner of being dismissive (unless that was your intention), but again, I fail to see how that helped the OP. And this is why a poster should add some text along his links. So now you know why I said it ;) Oct 6 '11 at 15:53
  • 1
    from the OP's mouth Is a coding style principle - e.g. the single-exit principle - really a good thing? - that gives context to the question he's posing, about coding styles. Furthermore, coding style is not the same as programming methodology, in particular high-level design methods which are the focus of the IEEE article (clearly stated by the authors.) That's why I say "no" - the scopes are completely different. Oct 6 '11 at 16:18
  • 1
    I suspect where the OP is coming from. He's clearly stating coding styles (not methodologies), and in particular, single vs multiple returns. I've had to cope with that a couple of times with well-written, inherently self-evident code using multiple return statements being rewrite into more convoluted versions using single-returns (in particular in large organizations big in red-tape) *as per "the process". And one wonders (and challenges with evidence) the validity, usability and cost-effectiveness of such arbitrary mandates. People who force such mandates still live in the 60's :/ Oct 6 '11 at 16:23

Is a coding style principle - e.g. the single-exit principle

People who still hark at whether to a single-exit or multiple exit are still stuck in the late 1960's. Back then, such a discussion was important since we were in the infancy of structured programmer, and there was a quite numerous camp proclaiming that the findings behind Bohm-Jacopini Structured Program Theorem weren't universally applicable to all programming constructs.

It is something that should have been settled long ago. Well, it has been settled (almost 4 decades to be precise, in both Academia and the industry), but people (those who are absolutely pro or against) have not been paying attention.

As for the rest of my answers, it's all relative (what isn't in software?):

  • really a good thing?

Yes. Most of the time for the general case, with caveats specific to edge cases and language-specific programming constructs.

Always, or just sometimes?

Most of the time.

How much difference does it really make?


Readable code vs unreadable code. Increased complexity (which we should know by now increases the probability of introducing errors) vs simpler complexity (and ergo, smaller probability of errors.) Languages whose compilers do not add an implicit return (say, Pascal, Java or C#) and those that default to int (C and C++).

In the end, it is a skill honed with man/hours behind a keyboard. Sometimes, it's ok to have multiple return statements, like here (in some Pascal'esque pseudocode):

function foo() : someType
  if( test1 == true )
    return x;
  return somethingElse();

The intent is clear, and the algorithm is small enough and uncomplicated enough that it does not warrant the creation of a 'flag' variable that holds the eventual return value used in a single return point. The algorithm could be in error, but its structure is simple enough that the effort in detecting an error is (most likely) negligible.

Sometimes it's not (here using a C-like pseudocode):

case v1 : return x1;
case v2 : return x2:
case v3 : doSomething(); // fall-through
case v4: // fall-through
case v5: // fall-through
case v6: return someXthingie;
   doSomething(); // no return statement yet

Here, the algorithm does not have a simple structure, and the switch statement (a C-style one) allows fall-through steps which may or may not done intentionally as part of the algorithm.

Maybe the algorithm is correct, but poorly written.

Or maybe, by external forces beyond the programmer's ability, this is the actual (and correct) representation of a legitimately needed algorithm.

Maybe it is wrong.

To uncover the truth of any of this requires far more effort than in the previous example. And herein lies something I strongly believe (mind you that I have no formal studies to back this up):

Assuming a code snippet that is assumed to be correct:

  1. Multiple return statements increase the readability and simplicity of such a code snippet, if the snippet represents a simple algorithm with an inherently simple flow structure. By simple, I don't mean small, but I mean inherently comprehensible or self-evidence, that which does not require disproportionate reading effort (nor induce people to vomit, curse someone's mother, or swallow a bullet when they have to read it.)

  2. A single return statement increases the readability and simplicity of such a piece of code if the return value is either calculated throughout the execution of the algorithm or if the steps in the algorithm responsible for calculating it can be grouped together in one location within the algorithm's structure.

  3. A single return statement decreases the readability and simplicity of such a piece of code if it requires assignments to one or more flag variables, with the locations of such assignments not being uniformly located throughout the algorithm.

  4. Multiple return statements decrease the readability and simplicity of such a piece of code if the return statements are not uniformly distributed across the algorithm, and if they demarcate mutually exclusive blocks of code that are not uniform in size or structure among themselves.

This is closely related to the complexity of a code snippet in question. And this in turn is related to cyclomatic and halstead complexity measures. From this, one could observe the following:

The larger the size of a subroutine or function, the larger and more complex its internal control flow structure is, and the greater the probability you'll face a question of whether to use multiple or single return statements.

The conclusion of this is: keep your functions small doing one thing and only one thing (and doing it well). If they exhibit nominally small cyclomatic and halstead complexity metrics, not only are they bound to be most likely correct and be implementation of tasks that are comprehensible, their inner structures will also be relatively self-evident.

Then, and only then you can quite easily and without losing much sleep, you can decide whether to use a single return and multiple returns without running much risks of introducing errors with either choice.

One could also look at all of this and suggest that when people struggle with the issue of single returns or multiple returns, it is because - either by inexperience, stupidity or lack of work ethics - they don't write clean code and tend to write monstrous functions with complete disregard of cyclomatic and halstead measures.

  • 1
    C++ return type does not default to int: there is no default return type so it must be specified in all cases.
    – Sjoerd
    Oct 6 '11 at 23:10
  • From before I wrote this question - programmers.stackexchange.com/questions/58237/…. Basically, I'm advocating awareness of the principle, but not strictly following it - if all the exit points are obvious, I'm happy. My point here - just because I mention a principle as an example doesn't mean I'm advocating that principle, and certainly not in it's strict form. My subjective opinion is just that, though - maybe there's a stronger argument for my view, or maybe there's a strong argument that I'm wrong.
    – user8709
    Oct 7 '11 at 5:16
  • What is "default to int" about?
    – curiousguy
    Jun 30 '18 at 16:59
  • I mean to say, and I should have qualified it, that most compilers will simply "shove" the value of an accumulator register as a return value if the code happens to have an execution branch w/o an explicit return value. That in effect means returning the result of the last arithmetic operation (whatever garbage that might be) in int form. And that would certainly be garbage (and ergo, undefined behavior) regardless of what the function intended to do in the first place. C and C++ can warn you, but compiles will let you compile unless you use -Werror or something similar. Jul 2 '18 at 14:17