Over the last two years, I’ve been writing a lot about programming languages and their quirks—especially Java and Python. For whatever reason, the more I wrote, the more I learned. As the knowledge began to snowball, I started to ask myself some deeper questions about what I had learned. One of those questions happened to be “what makes something bad practice?” At the moment, I’m not sure if I’m going to make this a recurring series, but today we’ll be looking specifically at the idea of multiple return statements.
Table of Contents
Introduction
If you’ve followed along at all, you’ve probably caught me using the phrase “x is considered bad practice,” but I often don’t have a rationale to back up the claim. Sometimes I’ll provide an example of some coding style backfiring, or I might even share a source. At the end of the day, however, I’m just following community conventions.
Naturally, I became bothered by my lackluster explanations. Sure, counterexamples do a great job of illustrating why a particular practice might be considered “bad,” but I really wanted to know more. You know, like:
- What’s the historical context behind a “bad” practice?
- Does the argument against a “bad” practice actually hold up?
As a result, I decided to do a bit of a case study on a few techniques considered bad practice, and examine them in great detail.
Case Study: Multiple Return Statements
In order to determine what makes something bad practice, I’ve decided to dig into some commonly accepted bad practices. The goal will be to deconstruct their arguments to try to figure out if there are any lessons to be learned overall.
To start, I wanted to take a look at the idea that having a function with multiple returns is an inherently bad idea. After all, I can come up with a handful of examples where I would prefer multiple return statements, so let’s see if we can track down the origin of this bad practice.
Reading
In order to understand the nuance behind this issue, it’s important to read up on it. After a handful of Google searches, I was able to find several articles on the subject:
- Coding Tip: Have a Single Exit Point
- Where did the notion of “one return only” come from?
- Single Function Exit Point
- Single-Entry, Single Exit, Should it Still be Applicable in Object-oriented Languages?
- Why Many Return Statements Are a Bad Idea in OOP
- Religious War #48,293: Single Vs. Multiple Returns
- Return Early, Return Often
Summary
Upon further research, it appears that the argument against multiple return statements comes from the “single entry, single exit” (SESE) principle of structured programming. According to that principle, a function should only have a single entry point and a single exit point. In this case, a single entry point meant that a function should only be entered from where it starts—not some arbitrary point in the middle. Meanwhile, a single exit point meant that a function shouldn’t exit to (not from) more than one place.
Of course, modern programming languages don’t necessarily allow you to do either of these things. Functions always start from the top and always return to their caller. That said, somehow the SESE principle has taken on a new form which suggests that using more than one return statements is bad practice.
If you do some digging, you’ll see arguments that cite code fragility and maintainability. In particular, a lot of folks don’t like multiple returns because they introduce new exit points that need to be taken into account as a part of the control flow.
In my own experience, I’ve seen a lot of professors tell students to avoid using multiple return statements. From my understanding, the rationale behind a blanket rule like this is to enforce a sort of discipline which pushes students toward better programming practices. In many cases, these professors provide examples where the rule can be broken—only after the students have enough experience to handle the nuance.
Counterarguments
One of the weirdest things I’ve noticed about the single exit principle is that almost no one supports it on the internet—at least not to the extreme. Yet, I still see and hear it cited enough for this debate to continue to be active.
At any rate, there are a few circumstances where I would absolutely use multiple return statements. In particular, any time I perform a linear search of a data structure, I return as soon as the item is found. Not only does returning early reduce code complexity, but it also makes the solution easier to read.
In addition, I’ve heard about the Guard Clause which essentially reduces code complexity by eliminating edge cases at the start of a function. I don’t think I’ve personally used it as I generally design functions without a lot of edge cases, but I can see why it would be useful.
That said, perhaps my favorite argument against the SESE principle has to be from Abby Fichtner who stated the following:
But the worst part is that if you’re setting a value and you choose – even after setting the appropriate value for this scenario – to keep processing, you risk inadvertently changing the value from the right one to an incorrect one.
When using programming languages that leverage state to their advantage, refusing to exit when you have the solution is risky. It means you just may corrupt your result due to all the additional processing that you wouldn’t have had to do if you had just exited early.
Finally, I noticed that many of the arguments for the SESE principle use examples that are convoluted. In many cases, the examples have more issues than multiple return statements.
The Verdict: Multiple Returns Are Okay
After looking at the evidence, I have to say that the multiple return statement rule is a bit antiquated. In fact, the modern school of thought seems to be to exit early as argued by Christina Burger. Specifically, Christina argues that returning early aligns nicely with test driven development (TDD). After all, the error test cases are practically written for you.
As with every software principle, there’s always a bit of nuance. I tend to dislike hard rules that use terms like “always” or “never.” Surely, there are places where a single return is ideal and other places where multiple returns are better. It’s up to you to make that decision.
With that said, that’s all I want to talk about on this subject. If you like this article and want to see more like it, let me know! Alternatively, you can check out some of these related articles:
- Stop Using Flags to Control Your Loops
- Improve Code Readability by Using Parameter Modes
- What Is a Magic Number And How Do We Fix It?
Likewise, you’re always welcome to further support the site by checking out this list containing my Patreon, YouTube channel, and Newsletter. Otherwise, have a good one!
Recent Posts
Python has a cool feature that allows you to overload the operators. Let's talk about what that means and how you might use it!
This week, we're hitting another beginner topic: the assignment operator. While the idea is simple, the concept is rich in related ideas like scope, iterable unpacking, and augmented assignment.