Start learning free

LESSON 123 OF 414 · WHILE LOOPS & FOR LOOPS

Infinite While Loops in Scala: Why They Happen and How to Fix Them

Lesson Read the full explanation

Loops bring great power but also great responsibility. The biggest danger when using loops is writing an infinite loop.

An infinite loop is a loop that never terminates. For example, if we forget to increment i in our previous example:

var i = 1
while(i < 5) {
	println(i)
	// i += 1 => forgot this
}

This program will never terminate as i will always have value 1 and thus the condition i < 5 will always be satisfied.

The program would basically print 1 forever never exiting the while loop.


Pro Tip:

As programmers, we want to make sure we never write infinite loops as they make our program run forever and completely unusable.


Assignment
Follow the Coding Tutorial and practice with infinite while loops!


Hint
Look at the examples above if you get stuck.


STEP 1 OF 1
    Ctrl + Enter to check

    SCALA · WHILE LOOPS & FOR LOOPS

    Infinite While Loops in Scala, explained

    What an infinite loop is

    A while loop checks its condition before every pass. If the condition never becomes false, the loop never ends. The program keeps running, and any println inside the body keeps printing.

    The simplest cause is forgetting to change the variable the condition depends on:

    var i = 1
    while (i < 5) {
        println(i)
        // nothing changes i here
    }
    

    Here i stays 1, so i < 5 is always true and the loop prints 1 forever. Adding i += 1 inside the body fixes it.

    The less obvious cause: a condition that can be skipped over

    The exercise shows a second cause. The code should print the odd numbers from 15 down to 1 and then stop:

    var counter = 15
    while (counter != 0) {
        println(counter)
        counter -= 2
    }
    

    The update is fine and the counter does move. The problem is the condition. The loop only stops when counter is exactly 0, but the counter takes the values 15, 13, 11, 9, 7, 5, 3, 1, -1, -3, and so on. Starting from an odd number and subtracting 2 always gives an odd number, so 0 is never reached. The counter jumps from 1 to -1, the test counter != 0 is still true, and the loop goes on forever with ever more negative numbers.

    Fixing it step by step

    1. Follow the variable through the last passes. Write down the counter after each pass. The sequence 3, 1, -1 shows that it passes 0 without landing on it.
    2. Decide what the loop should really wait for. It should keep going while there are positive numbers left to print. That is a range question, not an exact-value question.
    3. Replace != with a range check. counter > 0 is true for 15 down to 1 and false for -1, so the loop stops right after printing 1.
    var counter = 15
    while (counter > 0) {
        println(counter)
        counter -= 2
    }
    

    This prints 15, 13, 11, 9, 7, 5, 3 and 1, then stops. When the counter becomes -1 the condition is false.

    A rule of thumb

    Prefer <, <=, > or >= to != or == in loop conditions. A comparison with a range still works if the counter jumps past the boundary, because "greater than 0" stays false once the counter is below it. An exact comparison works only if the counter lands on that value, and a step size other than 1 makes that easy to get wrong.

    Common mistakes

    • Forgetting the update. The body never changes the variable the condition checks.
    • Updating in the wrong direction. Adding to a counter that the condition expects to shrink moves it away from the exit.
    • Testing for an exact value that is never hit. This is the case of this lesson: a step of 2 over an odd start never equals 0.
    • Updating the wrong variable. If the loop has two variables, the one in the condition must be the one that changes.

    Key takeaways

    • A loop ends only when its condition becomes false, so every run of the body must move the program toward that point.
    • Trace the last few values of the counter to see whether the condition can ever fail.
    • Use range comparisons rather than != to stop a loop that counts with a step larger than 1.
    Keep going with ScalaAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free