Part of Learn Lua with NeoVim

Learn Lua in Neovim: If Statements — if, elseif, else & Grade Calculator | Episode 7

Sandy LaneSandy Lane

Video: Learn Lua in Neovim: If Statements — if, elseif, else & Grade Calculator | Episode 7 by Taught by Celeste AI - AI Coding Coach

Take the quiz on the full lesson page
Test what you've read · interactive walkthrough

Lua If Statements: if, elseif, else, and a Grade Calculator

if condition then ... end for branching. elseif (one word, no space) for chained alternatives. else for the fallback. Build a grade calculator from a numeric score.

Conditionals are how programs make decisions. Today's example is a grade calculator — a numeric score in, a letter grade out — that walks every form of Lua's if statement.

The grade calculator

local score = 92

if score >= 90 then
  print("Grade: A")
elseif score >= 80 then
  print("Grade: B")
elseif score >= 70 then
  print("Grade: C")
elseif score >= 60 then
  print("Grade: D")
else
  print("Grade: F")
end

print("Your score: " .. score)

Five branches, one if, three elseifs, one else. Score 92 matches >= 90, so it prints "Grade: A" and skips the rest.

The basic shape

if condition then
  -- code that runs when condition is true
end

Three keywords frame every if:

  • if — start the conditional.
  • then — required after the condition; ends the test.
  • end — closes the block. (No braces. No indentation-based blocks.)

Forget then or end and you get a parse error.

Adding else

local age = 18

if age >= 18 then
  print("You can vote")
else
  print("Too young")
end

else is the fallback. Whatever doesn't match the if falls into the else branch.

Chaining with elseif

if score >= 90 then
  print("Grade: A")
elseif score >= 80 then
  print("Grade: B")
elseif score >= 70 then
  print("Grade: C")
end

elseif (one word, no space) is "else if" combined. Without it you'd write:

if score >= 90 then
  print("A")
else
  if score >= 80 then  -- nested if = ugly
    print("B")
  else
    -- ...
  end
end

Each level of nesting needs its own end. elseif flattens that — one end for the whole chain.

Order matters

The branches are evaluated top-to-bottom. The first matching condition wins; the rest are skipped. So:

if score >= 60 then
  print("D")
elseif score >= 90 then
  print("A")    -- never runs! the 60 branch matched first
end

For range checks, order from most-specific to least-specific (high to low for grades).

else is optional

if score < 0 then
  print("Invalid score")
end
-- continues to next line whether or not the if matched

Plain if with no else is fine. It just means "do this block if true; do nothing if false."

Nested ifs

local age = 18
local has_id = true

if age >= 21 then
  if has_id then
    print("Welcome")
  else
    print("Need ID")
  end
else
  print("Too young")
end

Two levels of if. Each one needs its own end. Often and is cleaner:

if age >= 21 and has_id then
  print("Welcome")
elseif age >= 21 then
  print("Need ID")
else
  print("Too young")
end

We cover and and or properly in episode 8 — they make conditional expressions a lot more compact.

What counts as truthy?

Recall from episode 5: only false and nil are falsy. Everything else is truthy.

if 0 then print("0 is truthy") end           -- prints
if "" then print("'' is truthy") end          -- prints
if "false" then print("'false' is truthy") end  -- prints (it's a non-empty string!)

For "is this number positive," check if x > 0 then, not if x then.

A common pattern: validate first

print("Enter your score:")
local score = tonumber(io.read())

if score == nil then
  print("That wasn't a number")
elseif score < 0 or score > 100 then
  print("Score out of range")
elseif score >= 90 then
  print("Grade: A")
elseif score >= 80 then
  print("Grade: B")
-- ...
end

Validate before computing. The first two branches catch bad input; the rest do the actual grading. Reads top-to-bottom like a checklist.

Single-line ifs?

Lua doesn't have a special syntax for one-liners — every if needs then and end. You can compress:

if x > 0 then print("positive") end

Works fine. But there's no Python-style print("positive") if x > 0. Lua keeps the syntax uniform.

Common stumbles

Forgetting then. if x > 0 print("yes") end is a syntax error. then is mandatory.

Forgetting end. Especially in nested ifs, missing one end triggers a confusing error like "expected 'end' near 'else'." Indent consistently and the missing end becomes obvious.

else if instead of elseif. else if opens a new nested if that needs its own end. elseif doesn't. Two different things.

Range checks in wrong order. if x > 60 ... elseif x > 90 ... — the second branch never runs. Order high-to-low for descending ranges.

Treating non-boolean values as booleans without thought. if user_input then matches any non-nil value, including the string "false". Compare explicitly when in doubt: if user_input == "yes" then.

What's next

Episode 8: logical operators. and, or, not — and the surprising x and a or b "ternary" idiom that takes advantage of how and/or actually work.

Recap

if condition then ... end for conditionals. elseif (one word) chains alternatives. else for the fallback. Branches evaluate top-to-bottom; first match wins. Only false and nil are falsy. Always close with end.

Next episode: and, or, not.

Ready? Take the quiz on the full lesson page →
Test what you've learned. Watch the lesson and try the interactive quiz on the same page.