Default Arguments

When a function parameter or class constructor parameter has a default value, callers can leave that argument 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 and never nil.

Your editor shows the default when you call the function.

Passing nil

Because passing nil is the same as leaving the argument out, you can 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 a 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