Skip to content
Lesson 7 of 18

Step 1 of 5 · Reading · ~3 min

Learn

Control Flow

If, Then, Else

Lua spells its conditional if ... then ... end. The then is not optional and neither is the end — no block in Lua is ever wrapped in braces, and every one of them closes with the word end.

local age = 18
if age < 13 then
    print("child")
elseif age < 20 then
    print("teen")
else
    print("adult")
end

--> teen

elseif is one word. Writing else if is legal, but it opens a nested if that needs its own end, which is a fast way to collect a syntax error at the bottom of a long ladder.

Operators that look different here

  • Equality is ==; inequality is ~=. Lua has no !=, and typing it is a syntax error rather than a subtle bug.
  • The logical operators are the words and, or, not — not &&, ||, !.
  • Assignment is a statement, never an expression, so if x = 1 then will not compile. The classic C bug of writing one = instead of two cannot happen here.
  • <, >, <=, >= compare two numbers or two strings. Comparing a number with a string is an error, not false.

What counts as true?

This is the most surprising rule in Lua for anyone arriving from C, Python, or JavaScript. Only false and nil are false. Every other value is true.

ValueIn a condition
nilfalse
falsefalse
0true
0.0true
""true
"0"true
{}true

✗ the zero-means-false habit

local count = 0
if count then
    print("we have items")
end

--> we have items

✓ say what you mean

local count = 0
if count > 0 then
    print("we have items")
else
    print("empty")
end

--> empty

Testing a plain variable is still the right move when you are asking "did I get a value at all?", because that is exactly the nil case.

and / or hand back values, not booleans

Both operators short-circuit, and both return one of their operands rather than true or false.

  • a and b gives a when a is false or nil, otherwise b
  • a or b gives a when a is truthy, otherwise b

That is where Lua's default-value idiom comes from:

local nickname = nil
print(nickname or "anonymous")

--> anonymous

Chaining the two makes a compact conditional expression, cond and a or b:

local n = 7
print(n % 2 == 0 and "even" or "odd")

--> odd

✗ but it collapses the moment the middle value is itself false or nil

print(true and false or "surprise")

--> surprise

The condition was true, yet the third value came out. When either branch can be false or nil, write a real if.

Ladders run top down, first match wins

Once a branch matches, everything below it is skipped. That makes the order of the tests part of the logic: the loosest condition has to come last.

Rendering diagram…

Because each test is only reached when every earlier one failed, you never need to write score >= 80 and score < 90. The ladder already knows the score is under 90 by the time it gets there.

Your exercise

Grade Calculator reads one integer score and prints a single letter.

Both mistakes the grader will catch are in that diagram. Order first: a ladder that opens with score >= 60 prints D for the input 95, because that branch matches and nothing below it ever runs — start at 90 and work down. Boundaries second: use >=, not >. One of the visible tests is exactly 60 and expects D, so score > 60 drops it through every remaining branch and prints F.

Up nextLoopsControl Flow

Discussion

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

Sign in to post a comment or reply.

Loading…