Lua Operators
Lua provides a compact set of operators grouped into a few families: arithmetic (+ - * / // % ^), relational (== ~= < > <= >=), logical (and or not), a string concatenation operator (..), and a length operator (#). Unlike many C-family languages, Lua uses ~= for 'not equal' instead of !=, and has no increment (++) or compound assignment (+=) operators at all — every update to a variable is written out explicitly, as in x = x + 1. Operator precedence follows fairly conventional rules, with ^ (exponentiation) binding tighter than unary minus, and .. and comparison operators binding looser than arithmetic.
Cricket analogy: Lua having no ++ shorthand, requiring x = x + 1 written out fully, is like a scorer manually updating the total after every run rather than using an automatic counter — more explicit, more verbose, but nothing happens implicitly behind the scenes.
Arithmetic and Relational Operators
Arithmetic operators include the familiar +, -, *, /, plus two Lua-specific ones: // for floor division and ^ for exponentiation (so 2 ^ 10 is 1024.0, always returning a float). The modulo operator % follows the mathematical definition a % b == a - math.floor(a/b)*b, meaning it correctly handles negative operands, unlike C's truncating modulo. Relational operators (== ~= < > <= >=) compare values and return a boolean; == between values of different types (like a number and a string) is always false without raising an error, while comparing incompatible types with < or > — like a number and a table — raises a runtime error rather than silently returning a result.
Cricket analogy: Lua's % correctly handling negative operands, unlike C, is like a net run rate calculation that correctly accounts for a team bowled out early, rather than a naive formula that breaks down under unusual match situations.
Logical Operators and Truthiness
Lua's logical operators are the words and, or, and not, not symbols like && and ||. Crucially, Lua treats only two values as falsy: false and nil — everything else, including 0 and the empty string "", is truthy, which trips up programmers coming from languages like Python or JavaScript where 0 is falsy. Both and and or are short-circuiting and return one of their operands rather than a strict boolean: a and b returns a if a is falsy, otherwise b; a or b returns a if a is truthy, otherwise b. This makes the common idiom x = x or default a concise way to assign a default value only when x is nil or false.
Cricket analogy: Only nil and false counting as falsy in Lua, unlike Python where 0 is falsy, is like a match only being declared a 'no result' due to rain or bad light — a score of 0 runs is still a completely valid, countable result, not treated as if the match didn't happen.
Concatenation and the Length Operator
The .. operator concatenates two strings, or a string and a number (Lua automatically converts numbers to their string representation), as in "Score: " .. 42 producing "Score: 42". Concatenation creates a new string each time, so building a large string inside a loop with repeated .. is inefficient — table.concat is the idiomatic, faster alternative for joining many pieces at once. The # operator returns the length of a string in bytes, or, for a table, the number of elements in its array part; because tables can have holes (missing indices) or mixed array/hash content, # on such a table is technically undefined behavior and may return any valid 'border' rather than the count you intuitively expect.
Cricket analogy: Building a long string with repeated .. inside a loop being inefficient is like a scorer rewriting the entire scoreboard from scratch after every single run instead of just updating the latest total — technically correct, but wasteful compared to table.concat's single, efficient pass.
-- Arithmetic
print(2 ^ 10) -- 1024.0 (exponent, always a float)
print(-5 % 3) -- 1 (Lua's modulo follows math floor semantics)
print(7 // 2) -- 3 (floor division)
-- Relational
print(1 == "1") -- false (different types, no error)
print(3 < 5 and "yes" or "no") -- "yes"
-- Logical / truthiness
local timeout = 0
local t = timeout or 30 -- t is 0, NOT 30, because 0 is truthy in Lua
print(t) -- 0
-- Concatenation and length
local name = "Aria"
local msg = "Player: " .. name .. ", Score: " .. 42
print(msg) -- "Player: Aria, Score: 42"
print(#name) -- 4 (string length in bytes)
local parts = {}
for i = 1, 5 do
parts[#parts + 1] = "item" .. i
end
print(table.concat(parts, ", ")) -- "item1, item2, item3, item4, item5"Because only nil and false are falsy in Lua, the common x = x or default idiom silently breaks if a legitimate value of 0, "", or false should be treated as 'set' — always check explicitly with if x == nil then when zero, empty strings, or booleans are valid data, rather than relying on truthiness.
- Lua's operators cover arithmetic, relational, logical, concatenation (
..), and length (#) — grouped into a small, fixed set. - There is no
++or+=; every update must be written explicitly, e.g.x = x + 1. /always returns a float;//performs floor division;^(exponentiation) also always returns a float.- Only
nilandfalseare falsy in Lua —0and""are both truthy, unlike Python or JavaScript. andandorshort-circuit and return one of their operands, enabling thex = x or defaultidiom.- The
..operator concatenates strings (and auto-converts numbers), but repeated use in a loop is inefficient — prefertable.concat. - The
#operator gives string length in bytes, but is undefined behavior on tables with holes.
Practice what you learned
1. Which operator does Lua use for 'not equal'?
2. Which of these values is falsy in Lua?
3. What does `10 // 3` evaluate to?
4. What does the idiom `x = x or default` do?
5. Why is `#` considered unreliable on some tables?
Was this page helpful?
You May Also Like
Lua Types and Variables
How Lua's dynamic typing, variable scope, number/string types, and tables work, with the specifics that trip up newcomers.
Your First Lua Script
Write, run, and structure a small real Lua script, covering command-line execution, comments, print, and basic input.
What Is Lua?
An introduction to Lua's history, design philosophy, and defining traits as a lightweight, embeddable scripting language.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics