Start learning free

LESSON 72 OF 348 · CONDITIONAL STATEMENTS

Redundant Else Statements in Kotlin

Lesson Read the full explanation

We will learn a simple trick to improve our code quality: removing redundant else statements.

Video Lesson:

STEP 1 OF 1
    Ctrl + Enter to check

    KOTLIN · CONDITIONAL STATEMENTS

    Redundant Else Statement in Kotlin, explained

    The idea

    Code can be correct and still carry extra weight. One common kind of extra weight is an else that does nothing a plain line after the if couldn't do. Removing it makes the code shorter and flatter, with the same behaviour.

    The starting code of the lesson is a function that always returns a value that is never positive:

    class Solution {
        fun negative(n: Int): Int {
            if (n < 0) {
                return n
            } else {
                return -n
            }
        }
    }
    

    It works. For a negative n it returns n and for anything else it returns -n. But look at what return does: it ends the function immediately. So by the time execution could reach anything after the first return, the function has already finished.

    Why the else isn't needed

    Follow the two cases.

    • When n < 0 is true, the first block runs, return n executes and the function ends. No later line is reached.
    • When n < 0 is false, the block is skipped and execution continues with the next line after the if block.

    So the code after the if already runs only when the condition was false. That is exactly what else promises, so writing else says the same thing twice. The word and its pair of braces add nothing.

    The exercise

    Remove the redundant part without changing what the function returns. Take out the else keyword, and with it the braces that opened and closed the branch. The if keeps its own closing brace, and the return -n moves out to the level of the if:

    class Solution {
        fun negative(n: Int): Int {
            if (n < 0) {
                return n
            }
            return -n
        }
    }
    

    The behaviour is identical: negative(4) returns -4, negative(-4) returns -4 and negative(0) returns 0. Two lines and a level of nesting are gone.

    Reading the cleaned-up version aloud gives a natural sentence: if n is below zero, give it back as it is; otherwise, give back its negation.

    Where this matters more

    With two branches the saving is small. With three or more outcomes, the effect on readability is large. This version uses else after every return:

    fun grade(score: Int): String {
        if (score < 50) {
            return "fail"
        } else if (score < 80) {
            return "pass"
        } else {
            return "distinction"
        }
    }
    

    And this version has no else at all:

    fun grade(score: Int): String {
        if (score < 50) {
            return "fail"
        }
        if (score < 80) {
            return "pass"
        }
        return "distinction"
    }
    

    Both give fail for 10, pass for 60 and distinction for 90. The second reads top to bottom as a list of special cases, each one handled and finished, followed by the general case.

    When you must keep the else

    The trick depends on the earlier branch really leaving the function. If a branch only prints, or assigns a variable, execution continues past the if block, and removing the else changes the behaviour:

    if (n < 0) {
        println("negative")
    }
    println("positive")
    

    For n = -2 this prints both lines. The original program, with the second println inside an else, printed only one. Before deleting an else, check that every path through the if block ends in return, or in something else that leaves, such as throw.

    Common mistakes

    • Removing the else but keeping its braces. In Kotlin, a bare { ... } after an if block is not a plain block. It is read as a lambda, so return inside it is rejected ("'return' is prohibited here") and the function reports a missing return. Remove the braces together with the else.
    • Dropping the final return. A function declared as returning Int needs a return on every path. With the else gone, the closing return -n is what covers the case where the condition is false.
    • Changing the logic while tidying. The cleanup should not alter the condition. Run the same examples before and after.

    Key takeaways

    • return ends the function, so code after an if that returns only runs when the condition was false.
    • In that situation, else is redundant and can be removed.
    • Flatter code with early returns is easier to read, especially with several cases.
    • Keep the else whenever the if block can finish without leaving the function.
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free