Default Arguments

Function parameters and class constructor parameters can have default values, and callers can leave those arguments out.

In Luau, you'd fill in missing arguments by hand:

local function greet(name: string, greeting: string?)
    local actual = greeting or "Hello"
    print(`{actual}, {name}!`)
end

greet("Ada")

In Luwu, the default goes in the signature:

const function greet(name: string, greeting = "Hello")
    print(`{greeting}, {name}!`)
end

greet("Ada")
greet("Grace", "Welcome")

Inside the function, greeting is always a string. It can never be nil.

Your editor shows the default when you call the function.

Passing nil

Passing nil is the same as leaving the argument out. That lets you skip one argument and pass the next.

const function spawn(kind: string, count = 1, level = 1)
    print(`{count} x {kind} at level {level}`)
end

spawn("slime")
spawn("slime", nil, 5)

Unlike x or default, a default argument doesn't replace false by mistake.

const function configure(verbose = true)
    print(verbose)
end

configure(false)

Defaults run on every call

A default is evaluated each time the function needs it. Every call gets its own fresh value.

const function new_inventory(items: { string } = {})
    return items
end

const first = new_inventory()
const second = new_inventory()
table.insert(first, "sword")
print(#first, #second)

A default can be any expression, including a function call:

local next_id = 0
const function make_id(): number
    next_id += 1
    return next_id
end
const function create_user(name: string, id = make_id())
    return { name = name, id = id }
end

print(create_user("Ada").id, create_user("Grace").id, create_user("Alan", 99).id)

Classes

A class's primary constructor takes defaults too:

class Enemy(name: string, hp = 100, speed = 1.0)
    function describe(self): string
        return `{self.name}: {self.hp} hp, speed {self.speed}`
    end
end

print(Enemy("Slime", 20):describe())
print(Enemy("Dragon", 5000, 0.5):describe())

Things to know