iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🔡

Language-Specific Syntax: Lua

に公開

This article is for the 20th day of the Programming Language Specific Syntax Advent Calendar 2025.

I will introduce some features along with my personal preferences.

Sample code for binary search

It is implemented by intentionally using the characteristics of the language.

-- Lua - table + metatable + coroutine
function binarySearch(arr, target)
    local left, right = 1, #arr

    while left <= right do
        local mid = math.floor((left + right) / 2)
        local value = arr[mid]

        if value == target then
            return mid
        elseif value < target then
            left = mid + 1
        else
            right = mid - 1
        end
    end
    return nil
end

local arr = {1, 3, 5, 7, 9}
print(binarySearch(arr, 5) or -1)  -- 3 (Lua is 1-indexed)

It is lightweight and well-known for being used as an embedded language in games. It has a minimalist design philosophy where everything is represented by a single "table".
Because it is so minimalist, there are few syntax features that feel unusual today.

Picked-up Syntax

Tables

The only data structure that can be used as both an array and an associative array.

-- As an array
local arr = {1, 2, 3, 4, 5}
print(arr[1])  -- 1 (starts at 1!)
print(#arr)    -- 5 (length)

-- As an associative array
local person = {
    name = "Alice",
    age = 30,
    ["key with space"] = "value"
}
print(person.name)  -- Alice
print(person["age"])  -- 30

-- Mixed
local mixed = {1, 2, 3, name = "test"}

Features like 1-indexing and having only a "table" structure are quite characteristic. Tables are similar to associative arrays in PHP.

Metatables

You can customize the behavior of tables to implement object-oriented programming and operator overloading.

-- Object-oriented style
local Vector = {}
Vector.__index = Vector

function Vector.new(x, y)
    return setmetatable({x = x, y = y}, Vector)
end

function Vector:length()
    return math.sqrt(self.x^2 + self.y^2)
end

-- Operator overloading
function Vector.__add(a, b)
    return Vector.new(a.x + b.x, a.y + b.y)
end

local v1 = Vector.new(3, 4)
print(v1:length())  -- 5

Coroutines

A lightweight thread feature for cooperative multitasking.

-- Cooperative multitasking
local co = coroutine.create(function()
    for i = 1, 3 do
        print("coroutine:", i)
        coroutine.yield(i)
    end
end)

coroutine.resume(co)  -- coroutine: 1
coroutine.resume(co)  -- coroutine: 2

-- Generator-like
function range(n)
    return coroutine.wrap(function()
        for i = 1, n do
            coroutine.yield(i)
        end
    end)
end

for i in range(5) do print(i) end

Operators and / or / not

Short-circuit evaluation allows for concise definitions of default values and conditional expressions.

-- Default values with short-circuit evaluation
local name = user_name or "anonymous"

-- Ternary operator-like
local result = condition and "yes" or "no"

-- nil check
if value ~= nil then
    -- not nil
end

Using and/or to simulate ternary operators is a common Lua idiom. ~= is also unique.

Variable-length Arguments

You can accept any number of arguments using ....

function sum(...)
    local args = {...}
    local total = 0
    for _, v in ipairs(args) do
        total = total + v
    end
    return total
end

print(sum(1, 2, 3, 4, 5))  -- 15
GitHubで編集を提案

Discussion