Skip to content
Lesson 8 of 18

Step 1 of 5 · Reading · ~3 min

Learn

Control Flow

Loops

Lua gives you three loop statements plus one iterator protocol. Which one you reach for depends on what you know before the loop starts.

Rendering diagram…

The numeric for

The header is for i = start, stop, step do, and both ends are inclusive. There is no < n in Lua: for i = 1, 5 really does visit 5.

for i = 1, 3 do
    print(i)
end
for i = 3, 1, -1 do
    print(i)
end

--> 1
--> 2
--> 3
--> 3
--> 2
--> 1

Three guarantees worth knowing, because beginners lean on them without realising:

  • The three numbers are evaluated once, before the first pass. Changing them inside the body does nothing to the loop.
  • i belongs to the loop. Assigning to it inside the body affects only that one pass, and after the loop i does not exist any more.
  • The default step is 1. Forgetting a negative step is the classic silent bug: for i = 10, 1 do counts upward from 10 to 1, an empty range, so the body never runs and nothing is printed at all.

✗ a float sneaking into the counter

for i = 1, 2, 0.5 do
    print(i)
end

--> 1.0
--> 1.5
--> 2.0

If any of the three numbers is a float, the counter is a float for the entire loop and every value prints with a .0 attached.

while and repeat

while tests before each pass. repeat tests after, so its body always runs at least once.

local n = 1
while n < 100 do
    n = n * 2
end
print(n)

--> 128
local i = 0
repeat
    i = i + 1
    local squared = i * i
until squared > 20
print(i)

--> 5

Look closely at that second one: squared is declared inside the body and still visible in the until condition. Lua deliberately extends the body's scope to cover the condition, which is what lets repeat ... until ok read the way you want it to.

break, and the missing continue

break leaves the innermost loop immediately. There is no continue in Lua at all.

✗ does not exist

for i = 1, 5 do
    if i % 2 == 0 then continue end
    print(i)
end

✓ invert the test and wrap the rest

for i = 1, 5 do
    if i % 2 ~= 0 then
        print(i)
    end
end

--> 1
--> 3
--> 5

Lua does have goto and a ::continue:: label as an escape hatch for deeply nested code, but restructuring with if is clearer and is what you will meet in most real Lua.

Looping over things that are not counters

The other for is the generic one, and it drives an iterator rather than a counter: for w in string.gmatch(line, "%S+") do. You have already used that shape to split a line into words. Tables bring their own iterators, ipairs and pairs, in the Tables chapter.

Your exercise

Multiplication Table reads one integer N and prints exactly ten lines shaped N x i = product, for i running 1 through 10.

The starter hands you the loop header; you write the line inside it.

The mistakes the grader will catch are bounds and separators. for i = 0, 10 emits eleven lines starting with 2 x 0 = 0, and for i = 1, 9 emits nine — the header is already correct in the starter, so leave it alone. The separator is a lowercase x with exactly one space on each side, which rules out print(n, "x", i, "=", n * i): that looks right on screen and writes tabs. Finally keep the arithmetic integral, because n * i prints 20 while anything routed through / or ^ prints 20.0.

Up nextTables as ArraysTables — The One Data Structure

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…