Functions
A function is a piece of script with a name, to be used again and again. print is one, and so is things.find. This page is about writing your own.
Making and calling one
local function greet(name)
print("Hello, " .. name .. "!")
end
greet("Sky")
greet("Moon")It prints
Hello, Sky!
Hello, Moon!name is the function's parameter: a variable that holds whatever the function was called with. Calling a function is writing its name with the values in brackets.
local function keeps the function to the block it is written in, like local does for a variable. Without local it is a global of the script.
Giving something back
return ends the function and hands a value back to whoever called it:
local function area(width, height)
return width * height
end
print(area(3, 4))It prints
12A function can give back several values, and several variables can take them:
local function middle(thing)
return thing.x + thing.w / 2, thing.y + thing.h / 2
end
local x, y = middle({ x = 2, y = 4, w = 6, h = 2 })
print(x, y)It prints
5 5return on its own leaves a function early and gives nothing back.
Too few values, too many
Calling a function with fewer values than it has parameters is fine: the rest are nil. Extra values are dropped. This makes parameters with a fallback easy:
local function shout(text, times)
times = times or 1
print(string.rep(text .. "!", times, " "))
end
shout("go")
shout("go", 3)It prints
go!
go! go! go!When a call that gives several values is not the last thing in a list, only its first value is used:
local function two()
return 1, 2
end
print(two(), "end") -- two() is cut to its first value
print("start", two())It prints
1 end
start 1 2Any number of values
Three dots take whatever values a function is called with. { ... } makes a list of them, and select("#", ...) counts them:
local function sum(...)
local total = 0
for _, n in { ... } do
total += n
end
return total, select("#", ...)
end
print(sum(1, 2, 3))It prints
6 3Functions are values
A function is a value like a number or a string. It can be kept in a variable, put in a table, and handed to another function. A function written without a name, right where it is needed, is how most events are answered:
level.beat:connect(function(beat)
print("beat " .. beat)
end)And it is how a list is sorted your way:
local scores = { 40, 90, 15 }
table.sort(scores, function(a, b)
return a > b -- the bigger one first
end)
print(table.concat(scores, " "))It prints
90 40 15Functions remember
A function can use the variables around it, and it keeps them for as long as it lives, even after the block they were made in has ended:
local function counter()
local count = 0
return function()
count += 1
return count
end
end
local tick = counter()
print(tick(), tick(), tick())It prints
1 2 3Each call of counter makes a count of its own, so two counters do not disturb each other.
Functions in tables
A table can hold functions, which is how the libraries are built: math.floor is the function floor in the table math. You can do the same:
local door = { open = false }
function door.toggle()
door.open = not door.open
print(door.open and "open" or "shut")
end
door.toggle()
door.toggle()It prints
open
shutThe colon
Written with a colon, a function gets the table it was called on as a hidden first parameter named self. That lets one function serve many tables:
local Door = {}
Door.__index = Door
function Door.new(name)
return setmetatable({ name = name, open = false }, Door)
end
function Door:toggle()
self.open = not self.open
print(self.name .. " is " .. (self.open and "open" or "shut"))
end
local front, back = Door.new("front"), Door.new("back")
front:toggle()
back:toggle()
front:toggle()It prints
front is open
back is open
front is shutfront:toggle() is short for front.toggle(front). The game's own values work this way too: door:tween(...), player:revive(), event:connect(...). Call those with a colon.
The line Door.__index = Door and setmetatable are explained under lists and tables.
A function calling itself
A function may call itself, as long as it stops somewhere:
local function countdown(n)
if n == 0 then
print("go!")
return
end
print(n)
countdown(n - 1)
end
countdown(3)It prints
3
2
1
go!Next: lists and tables.