Start learning free

LESSON 123 OF 348 · WHILE LOOPS & FOR LOOPS

Infinite For Loops in Kotlin: Why a Range Loop Ends

Lesson Read the full explanation

Remember the infinite while loop? Well, there is also such a thing called the infinite for loop.

Here is an example:

var i = 0
while (i < 10) {
    println(i)
    i--
    i++ // i++ from the loop update
}

This is what happens during this loop:

0. Creates and initializes a variable i = 0

1. First iteration:
	a. Is i < 10 true? <=> Is 0 < 10 true? Yes.
	b. Run the code inside {}:
        1) println(i) => Output: 0
	      2) i-- => i becomes -1
  c. i++ => i becomes 0 again

2. Second iteration:
	a. Is i < 10 true? <=> Is 0 < 10 true? Yes.
	b. Run the code inside {}:
        1) println(i) => Output: 0
	      2) i-- => i becomes -1
  c. i++ => i becomes 0 again

3. Third iteration:
	a. Is i < 10 true? <=> Is 0 < 10 true? Yes.
	b. Run the code inside {}:
        1) println(i) => Output: 0
	      2) i-- => i becomes -1
  c. i++ => i becomes 0 again

...

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

The program would basically print 0 forever never exiting the for loop.


Assignment
Follow the Coding Tutorial and let's practice with infinite for loops!


Hint
Look at the examples above if you get stuck.


STEP 1 OF 1
    Ctrl + Enter to check

    KOTLIN · WHILE LOOPS & FOR LOOPS

    Infinite For Loops in Kotlin, explained

    Can a Kotlin for loop run forever?

    In some languages a for loop has an update statement that the programmer writes, and a mistake in that statement can make the loop run forever. A Kotlin for (x in range) loop is different. It walks through a fixed sequence of values, and when the sequence is used up, the loop is over. The loop variable cannot be changed inside the body: x-- fails to compile with 'val' cannot be reassigned.

    This is a safety feature. If you rewrite a runaway while loop as a for loop over a range, the compiler and the range make sure it ends. The lesson's exercise does exactly that.

    The broken program

    This program should print the odd numbers from 15 down to 1 and then stop. It never stops:

    var number = 15
    while (number != 0) {
        println(number)
        number++
    }
    

    When you run it, you see 15, 16, 17, and so on, with bigger and bigger numbers. Two separate mistakes are involved.

    Mistake 1: the counter moves the wrong way

    number++ adds 1 on every pass. The loop waits for number to reach 0, and the value starts at 15 and moves away from 0. Adding 1 only gets back to 0 after the 32-bit Int passes 2147483647 and wraps around to a negative number, billions of passes later, so for practical purposes the program never stops.

    Mistake 2: the condition waits for an exact value

    Suppose the update were number -= 2. The values would be 15, 13, ..., 3, 1, -1, and so on. They are all odd, so none of them is 0, and the condition number != 0 would still be true forever. Even a correct direction fails here, because the step skips over the exact value being tested.

    The program also has a third problem that is not about stopping: with a step of 1, even a working loop would print every number, not only the odd ones.

    Fixing it step by step

    1. Replace the manual counter with a range. The loop should cover the values 15, 13, ..., 1. A progression describes that directly, so the var number declaration and the number++ line both go away.
    2. Count down. The sequence goes from 15 to 1, so use 15 downTo 1. The right end is 1 and is included.
    3. Take steps of 2. Add step 2. The step is positive, as Kotlin requires. The direction comes from downTo.
    4. Write the loop with its own variable. The variable number is now declared in the loop header, so the name from the original program stays the same.

    The solution in Kotlin

    for (number in 15 downTo 1 step 2) {
        println(number)
    }
    

    It prints 15, 13, 11, 9, 7, 5, 3 and 1 on separate lines, and then the loop ends by itself. The next value would be -1, which is below the end of the range.

    Why this loop cannot hang

    • The sequence is finite. 15 downTo 1 step 2 has exactly eight values, and the loop takes them one by one.
    • The step is checked. A step of 0 or a negative step throws an IllegalArgumentException with the message Step must be positive, was: 0. That is an error you see at once, rather than a program that runs forever.
    • The comparison is a range, not an exact match. The loop does not test number != 0. It asks whether there are values left, so skipping over any particular number does not matter.

    When you do need an infinite loop

    Sometimes a program should run until something happens, such as a user typing "quit". Kotlin's way to write this is while (true) with a break inside:

    var attempts = 0
    while (true) {
        attempts++
        if (attempts == 3) break
    }
    println(attempts)
    

    This prints 3. The loop is infinite in form but has a clear exit. If you cannot point to the exit, the loop is a bug.

    Common mistakes

    • Keeping the manual counter next to a range loop. A loop over a range does not need a var outside it.
    • Using a negative step. 15 downTo 1 step -2 throws an exception. Use downTo for the direction and a positive step.
    • Ending at 0 instead of 1. 15 downTo 0 step 2 still prints the same eight numbers, because the steps skip over 0. Ending at 1 says what you mean.
    • Starting at the wrong parity. Starting at 16 with a step of 2 would print even numbers.

    Key takeaways

    • A for loop over a range or progression ends when its values run out, and its loop variable cannot be modified in the body.
    • Waiting for an exact value with != hangs the loop whenever the counter steps over it, and counting in the wrong direction never reaches it.
    • The fix here is for (number in 15 downTo 1 step 2).
    • For deliberate endless loops, use while (true) with a break.
    Keep going with KotlinAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free