Start learning free

LESSON 128 OF 415 · WHILE LOOPS & FOR LOOPS

Infinite Loops in Swift: Fixing a Loop with stride

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 {
    print(i)
    i -= 1
    i += 1
}

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) print(i) => Output: 0
	      2) i -= 1 => i becomes -1
        3) i += 1 => i becomes 0 again

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

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

...

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

    SWIFT · WHILE LOOPS & FOR LOOPS

    Infinite For Loops in Swift, explained

    Loops that never finish

    An infinite loop keeps running because its condition never becomes false. A while loop can do this in several ways. One way is a body that undoes its own progress:

    var i = 0
    while i < 10 {
        print(i)
        i -= 1
        i += 1
    }
    

    Each pass prints 0, subtracts 1 and adds 1 again, so i is 0 at the start of every pass. The condition i < 10 stays true and the program prints 0 forever. The counter is updated, but the updates cancel out.

    Swift's for-in loop over a range or a stride avoids this class of bug, because the loop, not your code, moves to the next value.

    The exercise

    The program should print the odd numbers from 15 down to 1 and then stop. The starting code is:

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

    It prints 15, 16, 17 and so on without ever stopping. There are two mistakes, and both show up in the last line of the body and in the condition.

    1. The counter moves the wrong way. number += 1 makes the number bigger, but the target is below the start. It goes 15, 16, 17 and moves further from 0 each pass.
    2. The condition waits for an exact value. Even with the right direction, counting down by 2 from 15 gives 13, 11, ..., 3, 1, -1. The value 0 is skipped, so number != 0 is true on every pass.

    The fix

    Both problems disappear if the loop is written as a for-in over a stride:

    1. Choose the start and the step. Start at 15 and step by -2, so every value is odd and the numbers go down.
    2. Choose the end. The last number to print is 1, and the task includes it, so use through: 1.
    3. Drop the manual update. The loop declares its own constant number and moves to the next value by itself. There is no var to initialise and nothing to increment.
    for number in stride(from: 15, through: 1, by: -2) {
        print(number)
    }
    

    The loop prints 15, 13, 11, 9, 7, 5, 3 and 1, then stops, because the next value, -1, is past the end.

    Fixing it and keeping the while loop

    You could keep the while loop by fixing both mistakes: subtract 2 and use a range check instead of != 0.

    var number = 15
    while number > 0 {
        print(number)
        number -= 2
    }
    

    This prints the same eight numbers. The for version is shorter and leaves no counter to forget.

    Common mistakes

    • Fixing only one mistake. Changing += 1 to -= 2 and keeping != 0 still never stops, because the counter skips 0.
    • Using to: 1. stride(from: 15, to: 1, by: -2) excludes 1, so the last number printed is 3.
    • A positive step. stride(from: 15, through: 1, by: 2) is empty because the step moves away from 1, so nothing is printed.
    • Changing the loop variable inside the body. The variable of a for-in loop is a constant, so number -= 2 inside the loop does not compile.

    Key takeaways

    • A loop is infinite when its condition never turns false, for instance when the counter moves the wrong way or cancels its own update.
    • An != test can be jumped over; a range check such as > 0 cannot.
    • A for-in loop over stride ends on its own and manages the counter for you.
    Keep going with SwiftAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free