11

With pylint, I know that R1705 warning gets triggered when you put a 'return' inside an 'else'.

This is the warning: R1705: Unnecessary "else" after "return" (no-else-return)

This is what the docs says about it:

Unnecessary “else” after “return” Used in order to highlight an unnecessary block of code following an if containing a return statement. As such, it will warn when it encounters an else following a chain of ifs, all of them containing a return statement.

A snippet of code that will trigger R1705:

if CONDITION1:
   return something1
else:
   return something2

The desired fix to shut down the warning:

if CONDITION1:
   return something1
return something2

Is it really needed to obey this? What's the benefit? I mean I understand that after returning something from a function there is no way to come back and read further code.

But I find it way more organized to use 'else'.

Alex M.M.
  • 501
  • 1
  • 7
  • 18
  • 2
    The `else` is just redundant because it's already obvious where control will go if the condition isn't met. It also saves a level of indentation in the `else` clause. Of course, you may not want to write code like this because you "find it way more organized to use `else`". It's really up to you, to my mind. – ForceBru Apr 07 '19 at 16:26
  • Thank you ForceBru! I was afraid of something 'punishable' :) – Alex M.M. Apr 07 '19 at 16:44

2 Answers2

12

If you're trying to conform to Mozilla Coding Style or similar then R1705 makes sense. Quoting:

Don't put an else right after a return (or a break). Delete the else, it's unnecessary and increases indentation level.

Otherwise, you might prefer to disable that warning. Better still, consider switching to flake8, which tends to stay pretty silent if you've been writing sensible code.

Outside of the Mozilla community, most folks would rather see simple parallel functional clauses handled with an else, like this:

def max(a, b):
    if a > b:
        return a
    else:
        return b
J_H
  • 17,926
  • 4
  • 24
  • 44
5

This post gives two different cases for this design decision:

  1. Guard clauses.

    def try_something()
        if precondition():
             result = compute_something()
             return result
        else:
             display_error()
             return None
    

The author argues that for several such conditions their inversion and implicit else is better:

    # Implicit else, inverted condition
    def try_something():

        if not precondition_one():
            display_error_one()
            return

        if not precondition_two():
            display_error_two()
            return

        result = compute_something()
        return result
  1. Symmetrical clause.

    # Explicit else
    def check_link(link) -> bool:
        if is_internal_link(link):
            return check_internal_link(link)
        else:
            return check_external_link(link)
    

I agree with the author that here explicit is better.

I would also cite a comment from that post, which says that this choice is a choice of paradigm:

  1. "Explicit else": "if-then-else" is treated as lazy computation and more suited in "functional-first" environments. If this "if-then-else" is applied to large datasets and code in F#, Scala, Haskel, Closure or even SQL - explicitness is preferred. Most probably language/platform itself will encourage to write "pure" code and discourage/make near impossible to make imperative stunts.
  2. "Implicit else/(explicit return)": computation depends on 100% on side-effects and result is combination of side-effects too. It's impossible to guarantee correctness in strict sense anyway, so explicit return becomes clear declaration: "Because of laws of physics in our Universe, this computation could work incorrect. In majority of such cases this default value will be returned".
Yaroslav Nikitenko
  • 1,695
  • 2
  • 23
  • 31