Functions
In Luwu, functions are values. You can store them in variables and tables, pass them to other functions and create new ones while the program runs.
Declaring and calling
const function greet(name: string): string
return `Hello, {name}!`
end
print(greet("Ada"))Hello, Ada!
const function declares a function that can't be reassigned. The local function you'll see in Lua and Luau code works in Luwu too. name: string says the parameter name takes a string and the : string after the parentheses says the function returns one. return ends the function and hands its value back to the caller.
Arguments
A missing argument is nil and an extra one is ignored. Luwu's type checker reports both before the code runs. Give a parameter a default value for calls that leave it out:
const function cheer(message: string, times = 1)
for _ = 1, times do
print(message)
end
end
cheer("go!")
cheer("again!", 2)go! again! again!
Default Arguments covers defaults for functions and class constructors in more depth.
Returning several values
A function can return more than one value. List them after return and receive them with several names on the left of =:
const function min_max(numbers: { number }): (number, number)
local low, high = math.huge, -math.huge
for _, n in numbers do
low = math.min(low, n)
high = math.max(high, n)
end
return low, high
end
const low, high = min_max({ 72, 95, 88 })
print(`{low} to {high}`)72 to 95
Every value is kept only when the call comes last in a list of expressions. Anywhere else the call is cut down to its first value:
const function pair(): (string, string)
return "a", "b"
end
const last = { pair() }
const not_last = { pair(), "c" }
print(table.concat(last, " "))
print(table.concat(not_last, " "))a b a c
Functions are values
A function written without a name is an anonymous function. It's a value like any other and most often gets passed straight to another function. table.sort takes one that says whether a goes before b:
type Player = { name: string, score: number }
const players: { Player } = {
{ name = "Ada", score = 72 },
{ name = "Grace", score = 95 },
{ name = "Alan", score = 88 },
}
table.sort(players, function(a: Player, b: Player): boolean
return a.score > b.score
end)
print(players[1].name)Grace
Functions can be stored in tables too. Luwu lets you declare them by name inside a table literal.
Closures
A function created inside another function can use the outer function's locals and keeps them alive after the outer function returns. Such a function is called a closure. Each call to make_counter below creates a new count for its counter:
const function make_counter(): () -> number
local count = 0
return function()
count += 1
return count
end
end
const next_ticket = make_counter()
next_ticket()
next_ticket()
print(next_ticket())3
Any number of arguments
A function that ends its parameters with ... takes any number of arguments. { ... } collects them into an array:
const function sum(...: number): number
local total = 0
for _, n in { ... } do
total += n
end
return total
end
print(sum(1, 2, 3, 4))10
Method calls
Calling with a colon passes the value before it as the first argument. name:upper() means string.upper(name) and account:deposit(5) means account.deposit(account, 5). Strings get their methods from the string library this way:
const name = "nyla"
print(name:upper())
print(("meow"):rep(3))NYLA meowmeowmeow
In Luwu, methods on your own data usually come from classes. A class groups data with the methods that work on it and protects that data from changes that would make it invalid.