Lua from the ground up

Loops

Repeating work with while and for, counting up and down, and leaving a loop once you are finished with it.

Part 4 of 12

Beginner15 min readBack to Courses

while

A while loop repeats a block as long as its condition stays true. You are in charge of the thing that changes, so a loop that never changes it will never stop.

The condition is checked before each pass, which means the block may run zero times if it was false from the start.

The numeric for

When you know how many times to repeat, a numeric for says it in one line: for i = 1, 5 do. It counts from the first number to the second, and an optional third number is the step between the values.

The counting variable exists only inside the loop. A step of -1, or -3, counts down, and the loop stops when it would pass the finish.

repeat until, and break

A repeat ... until loop checks its condition at the end, so the block always runs at least once. The condition is the reason to stop, not the reason to continue, which reads backwards until you get used to it.

To leave a loop early, use break. It jumps out of the nearest loop, which is how you stop searching once you have found what you wanted.

What a numeric for really does

Lua works out the start, finish and step once, before the first pass. The control variable belongs to the loop, so assigning to it inside the body does not change the sequence: the next pass still uses the values the loop calculated.

The loop stops when the next value would pass the finish, which is why a step of -1 counts down and a step of -3 skips every third number. A step of zero is rejected with an error, because the loop could never reach its end.

Conditions at the top, and at the bottom

while checks before the block, so it can run zero times. repeat ... until checks after the block, so it always runs once. The until condition is the reason to stop; writing it as the reason to continue is the classic off-by-one.

A repeat body and its condition share a scope, so a local made in the body is still visible in the until. That is occasionally useful and always worth recognising when you read someone else's loop.

A loop that counts down

for i = 10, 1 do runs zero times, because the default step is +1 and the start is already past the finish. To count down you must say so: for i = 10, 1, -1 do. The same rule explains why a step of -3 from ten visits ten, seven, four and one, then stops before minus two.

A while countdown needs the same care in a different place. The condition while n > 0 and the line n = n - 1 have to agree; if the body decrements before printing, the last value printed is one lower than you expected. Trace the first and last pass, not the middle.

Accumulating a result

Most loops build something: a total, a longest word, a list. The pattern is always the same. Set the starting value before the loop, update it inside, and read it after the loop ends. A total starts at zero; a maximum starts at the first item, not at zero, or every negative value loses.

The mistake is declaring the accumulator inside the body. It is then a fresh local on every pass, so the work of the previous pass is gone. Lua will not warn: the loop still runs and still prints, just with the wrong number. Declare it above the for or while, in the scope where the answer has to survive.

Counting three ways

local i = 1
while i <= 3 do
  print("while " .. i)
  i = i + 1
end

for n = 1, 3 do
  print("for " .. n)
end

for n = 10, 1, -3 do
  print("step " .. n)
end

Three loop mistakes. A while whose body never changes the tested value runs forever. A numeric for with a step of zero raises an error instead of repeating. And break leaves only the loop it is written in, so a nested loop needs a flag when you want out of both.

Try these next

  • Print a 4 by 4 multiplication table with a for inside a for.
  • Search the numbers 1 to 50 for the first multiple of 7 and break as soon as you find it.
  • Write the same countdown with repeat ... until and with while, and compare the last number each prints.

Up, down, and a running total

Run it and trace how the total climbs. Then change the while loop to run five times, and add a break that stops the counting for loop at three.

Output
Click "Run" to execute your code

A table of products, and a search

Run it and trace one row. Then change the table to 1 to 5, and make the search stop at the first number divisible by 9 instead of 7.

Output
Click "Run" to execute your code

A loop that will not end is the most common beginner mistake. If a program seems to hang, look for the line that changes the value the while condition tests, and check that it really runs on every pass.

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

When is a while condition checked?