Start learning free

LESSON 49 OF 348 · FUNCTIONS I

Code After return in Kotlin: Fixing the Buggy Code

Practice Read the full explanation

We've written a program and expected it to print:

Hey bro!
How are you doing?

but we get a different output. Fix our code so that it prints what we want.

STEP 1 OF 1
    Ctrl + Enter to check

    KOTLIN · FUNCTIONS I

    Buggy Code 6 in Kotlin, explained

    What the code is supposed to do

    The program should print two lines:

    Hey bro!
    How are you doing?
    

    The function greetAndReturn has two jobs. It prints Hey bro! itself, and it returns the string "How are you doing?". The function mainFunction calls it, stores the returned string in question and prints it. Together they should produce both lines, in that order.

    The starting code prints only the second line:

    fun greetAndReturn(): String {
        return "How are you doing?"
        println("Hey bro!")
    }
    

    What goes wrong

    A return statement does two things at once: it gives a value back to the caller, and it ends the function immediately. Whatever sits below the return is never executed. Here, the println("Hey bro!") line comes after the return, so the function is already finished by the time it would run.

    Following the program through shows it:

    1. mainFunction calls greetAndReturn().
    2. The function hits return "How are you doing?" and leaves, taking that string with it.
    3. question is set to "How are you doing?".
    4. println(question) prints it.

    The code still compiles and runs without an error. That is what makes this kind of bug easy to miss: the program is valid, it just doesn't do everything you can see written in it.

    Fixing it step by step

    1. Decide the order of events. Hey bro! must be printed first, and the returned text is printed afterwards by mainFunction. The function therefore has to print before it returns.
    2. Move the println line up. Put it above the return, inside the same function body. The text and the function don't change; only the order of the two lines does.
    3. Keep the return as the last statement. Everything the function must do goes before it.

    The fixed code in Kotlin

    fun greetAndReturn(): String {
        println("Hey bro!")
        return "How are you doing?"
    }
    
    fun mainFunction() {
        val question = greetAndReturn()
        println(question)
    }
    

    Now the run goes like this. greetAndReturn() prints Hey bro! while it runs, then returns the string. Back in mainFunction, question holds the string, and println(question) prints it as the second line.

    A few Kotlin details:

    • The header fun greetAndReturn(): String promises a String. A function with a declared return type other than Unit must return a value on every path, and the final return does that.
    • val question = greetAndReturn() has no type written, and none is needed: Kotlin infers String from the function's return type.
    • The call to greetAndReturn() is where Hey bro! gets printed. Storing the result in a variable doesn't change that; the function body runs fully when it is called.

    When skipping code is the point

    Ending a function early is useful when you do it on purpose. In this function, a return inside an if skips the rest of the body for some inputs only:

    fun describe(n: Int): String {
        if (n < 0) {
            return "negative"
        }
        println("checked $n")
        return "not negative"
    }
    

    Calling describe(-5) returns "negative" without printing anything. Calling describe(3) prints checked 3 and then returns "not negative". In the buggy code, the return has no condition, so it ends the function every time.

    Common mistakes

    • Printing the greeting from mainFunction instead. That can print the same two lines, but the function is meant to print its greeting itself, and this lesson's code expects it there.
    • Deleting the return line. The function promises a String, so removing the return is a compile error.
    • Putting the println after the return in a different shape. Any statement placed after a return that always runs is skipped, whether it is a print, an assignment or a call.
    • Swapping the output order by mistake. If the text is returned and printed by the caller, it appears after everything the function printed, because the caller only prints once the function has finished.

    When a function seems to skip a line, look above that line for a return.

    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free