Globals

Embedders: to define globals within your environment, see userdata (extern types)

All language-provided globals that should be in scope in every program (unless the embedder removes or replaces them)

Summary

Output

printLua
Writes its arguments to the output separated by tabs

Error handling

assertLua
Raises an error when a value is falsy
errorLua
Raises an error with any value as the error object
pcallLuaLuau
Calls a function and catches any error it raises
xpcallLuaLuau
Calls a function and passes any error it raises to a handler

Types and conversions

typeLuaLuauLuwu
Returns the name of a value's basic type
typeofLuauLuwu
Returns a value's type name, using the host's names for its types
tonumberLua
Converts a value to a number or returns nil
tostringLua
Converts any value to a string

Iterators

nextLua
Returns the table entry that comes after a key
pairsLuadeprecated
Returns what a for loop needs to visit every entry of a table
ipairsLuadeprecated
Returns what a for loop needs to visit an array in order

Varargs

selectLua
Returns the argument count or the arguments from an index on
unpackLua
Returns the items of an array between two indices

Metatables

getmetatableLua
Returns the metatable of a value
setmetatableLua
Sets the metatable of a table
rawgetLua
Reads a table field without calling __index
rawsetLua
Sets a table field without calling __newindex
rawequalLua
Checks whether two values are equal without calling __eq
rawlenLuau
Returns the length of a table or string without calling __len
newproxyLuadeprecated
Creates an empty userdata, optionally with a metatable

Modules

requireLuaLuau
Runs a module and returns the value it returns

Environments

_GLua
The global table
getfenvLuaLuaudeprecated
Returns the environment table of a function
setfenvLuaLuaudeprecated
Sets the environment table of a function

Debugging

gcinfoLua
Returns the total heap size in kilobytes
_VERSIONLua
A string naming the runtime

Primitives

noneLuwuflagged
The value that means intentionally empty

Output

printLua

function print(...: unknown)

Writes each argument to the environment's output or debug console as a string separated by tabs.

Environment-specific overrides

Embedders often override this function to add pretty printing, output to a logfile, or remove it altogether in environments without a console.

In Luwu, we expect embedders to (eventually) call __tostring on each argument, but embedders often call an embedder-defined display implementation on each argument before falling back to it. In the near future we're interested in introducing language-level __repr, __display, and __debug functions to granularly specify the semantic meaning of tostring representations across multiple environments.

Error handling

assertLua

function assert<T>(value: T, message: string?): T

Raises an error when value is falsy (false, nil or none). The error message is message when it's given and "assertion failed!" otherwise. When value is truthy, assert returns every argument it was passed.

The type checker narrows the result. Passing a number? gives back a number:

Input
const gold: number? = 120
const amount = assert(gold, "gold should be set")
print(amount + 5)
Output
125

errorLua

function error<T>(message: T, level: number?): never

Raises an error with message as the error object. The object doesn't have to be a string: pcall hands back whatever value was raised.

When message is a string, error puts the location of the call at level in front of it. Level 1 (the default) is the function that called error, level 2 is the function that called that one, and level 0 leaves the message as it is. Level 2 blames the caller when it passed a bad argument:

const function withdraw(balance: number, amount: number): number
    if amount > balance then
        error("not enough gold", 2)
    end
    return balance - amount
end

pcallLuaLuau

function pcall<A..., R...>(f: (A...) -> R..., ...: A...): (boolean, R...)

Calls f with the remaining arguments and catches any error it raises. On success it returns true followed by everything f returned. On failure it returns false and the error object. f can yield and the whole coroutine yields with it.

Input
const ok, doubled = pcall(function(amount: number): number
    return amount * 2
end, 21)
print(`{ok} {doubled}`)

const failed = pcall(error, "out of gold")
print(failed)
Output
true 42
false

xpcallLuaLuau

function xpcall<E, A..., R1..., R2...>(
    f: (A...) -> R1...,
    handler: (E) -> R2...,
    ...: A...
): (boolean, R1...)

Works like pcall except that an error goes through handler first. xpcall then returns false and the handler's first result. The handler runs before the stack unwinds and debug.traceback can see where the error happened from inside it.

f can yield. The handler can't: when it yields or raises an error, xpcall returns false and "error in error handling".

const ok, result = xpcall(load_save, function(err: unknown): string
    return debug.traceback(tostring(err), 2)
end, "slot1")

Types and conversions

typeLuaLuauLuwu

function type(value: unknown): string

Returns the name of the value's primitive type, like "number" or "table". Primitives lists every one.

type never looks at metatables and calls every userdata "userdata". typeof gives the host's name for it instead.

Input
print(type(42))
print(type("Ada"))
print(type(print))
print(type(buffer.create(8)))
Output
number
string
function
buffer

typeofLuauLuwu

function typeof(value: unknown): string

Returns the same name as type except for values whose type the host has named. A host-defined userdata whose metatable has a __type string gives that string. Userdata from newproxy always gives "userdata" and scripts can't make a value pass for a host type. typeof(none) is "none".

Input
print(typeof(42))
print(typeof(none))
Output
number
none

tonumberLua

function tonumber(value: unknown, base: number?): number?

Converts value to a number and returns nil when it can't. Numbers come back unchanged. In base 10 (the default), a string can be written any way a number literal can be written. That covers hexadecimal like "0x1F" and exponents like "1e3". Spaces around the number are allowed. Any other base from 2 to 36 reads the string's digits in that base, using letters for digits past 9.

Input
print(tonumber("42"))
print(tonumber("ff", 16))
print(tonumber("0x1F"))
print(tonumber("12 gold"))
Output
42
255
31
nil

tostringLua

function tostring(value: unknown): string

Converts any value to a string. When the value's metatable has a __tostring metamethod, tostring calls it and returns the string it gives back. A __tostring that returns anything else raises an error. Tables, functions and other objects without one convert to their type and an address, like "table: 0x0000a1b2c3d4e5f6".

Input
const purse = setmetatable({ amount = 120 }, {
    function __tostring(self: { amount: number }): string
        return `{self.amount} gold`
    end,
})
print(tostring(purse))
print(tostring(none))
Output
120 gold
none

Iterators

nextLua

function next<K, V>(t: { [K]: V }, key: K?): (K?, V)

Returns the key and value that come after key in the table's traversal order, or nil after the last one. With key left out or nil, it returns the first entry. The order isn't defined. next(t) == nil checks whether a table is empty:

Input
const empty = {}
const gold = { Ada = 120 }
print(next(empty) == nil)
print(next(gold) == nil)
Output
true
false

pairsLuadeprecated

function pairs<K, V>(t: { [K]: V }): (({ [K]: V }, K?) -> (K?, V), { [K]: V }, nil)

Returns the three values a for loop needs to visit every entry of a table. The order isn't defined. for key, value in t do does the same without the call. Unlike pairs, it runs the table's __iter metamethod.

ipairsLuadeprecated

function ipairs<V>(t: { V }): (({ V }, number) -> (number?, V), { V }, number)

Returns the three values a for loop needs to visit an array in order. The loop starts at index 1, counts up by one and stops at the first nil. Items after a hole are skipped. A none in the array doesn't stop the loop.

Input
const queue = { "Ada", "Grace", nil, "Alan" }
for index, name in ipairs(queue) do
    print(`{index}: {name}`)
end
Output
1: Ada
2: Grace

Varargs

selectLua

function select<A...>(index: number | "#", ...: A...): ...unknown

With "#" as the first argument, select returns the number of arguments after it including any nil ones. With a number, it returns the arguments from that index on. A negative index counts from the end: -1 is the last argument.

Input
const function count(...: unknown): number
    return select("#", ...)
end
print(count(1, nil, 3))

const last = select(-1, "Ada", "Grace", "Alan")
print(last)
Output
3
Alan

unpackLua

function unpack<V>(t: { V }, first: number?, last: number?): ...V

Returns the items of t from index first (1 by default) to last (#t by default). It's the same function as table.unpack.

Input
const second, third = unpack({ "Ada", "Grace", "Alan" }, 2)
print(`{second} and {third}`)
Output
Grace and Alan

Metatables

getmetatableLua

function getmetatable<T>(value: T): getmetatable<T>

Returns the metatable of value or nil when it has none. Values other than tables and userdata share one metatable per type: every string has the metatable whose __index is the string library. When the metatable has a __metatable field, getmetatable returns that field instead and it doesn't have to be a table.

setmetatableLua

function setmetatable<T, MT>(t: T, metatable: MT): setmetatable<T, MT>

Sets the metatable of t and returns t. Passing nil removes the metatable. Only tables work here, unlike getmetatable. When the current metatable has a __metatable field it's protected and setmetatable raises an error.

Input
const defaults = { speed = 16 }
const player = setmetatable({ name = "Ada" }, { __index = defaults })
print(player.speed)
print(rawget(player, "speed"))
Output
16
nil

rawgetLua

function rawget<K, V>(t: { [K]: V }, key: K): V?

Reads t[key] without calling an __index metamethod. It returns nil when the table itself has no value under key.

rawsetLua

function rawset<K, V>(t: { [K]: V }, key: K, value: V): { [K]: V }

Sets t[key] to value without calling a __newindex metamethod and returns t.

rawequalLua

function rawequal(a: unknown, b: unknown): boolean

Returns whether a and b are the same value without calling an __eq metamethod. Tables, functions and other objects are equal only when they're the same object.

rawlenLuau

function rawlen<K, V>(value: { [K]: V } | string): number

Returns the length of a table or string without calling a __len metamethod. For a string it's the same as #s.

newproxyLuadeprecated

function newproxy(with_metatable: boolean?): userdata

Creates an empty userdata. When with_metatable is true, it gets an empty metatable that getmetatable returns and scripts can fill in. typeof always gives "userdata" for these values, even when the metatable has a __type field. A script can't use them to pass for a host's type.

Modules

requireLuaLuau

function require(path: string): unknown

Runs a module and returns the value it returns. A module runs once and later calls with the same module get the same value. The host provides require and decides how paths resolve. Hosts that use Luwu's Require library follow the same rules:

The type checker follows a require of a literal path and gives the result the module's type.

const inventory = require("./inventory")
const colors = require("@std/io/colors")

Environments

_GLua

_G: { [string]: unknown }

The global table. Reading _G.name is the same as reading the global name. In a sandboxed host the global table is read-only.

getfenvLuaLuaudeprecated

function getfenv(target: (number | (...unknown) -> ...unknown)?): { [string]: unknown }

Returns the environment table of a function. target is either the function or a level on the call stack, where 1 (the default) is the function calling getfenv. For a function written in C, getfenv returns the thread's global table.

getfenv and setfenv mark the environment as unsafe. Code using that environment loses the optimizations that rely on globals never changing, such as fast calls to builtin functions.

setfenvLuaLuaudeprecated

function setfenv<T..., R...>(
    target: number | (T...) -> R...,
    env: { [string]: unknown }
): ((T...) -> R...)?

Sets the environment table of a function to env and returns the function. target is the function or a level on the call stack, where 1 is the function calling setfenv. Level 0 changes the running thread's environment and returns nothing. Functions written in C can't have their environment changed. Like getfenv, it turns off the optimizations that rely on globals never changing.

Debugging

gcinfoLua

function gcinfo(): number

Returns the total heap size in kilobytes. The heap includes bytecode, global tables and every object scripts allocated. Luwu's garbage collector is incremental and the heap can hold unreachable objects it hasn't freed yet. The number changes as the collector runs.

_VERSIONLua

_VERSION: string

A string naming the runtime. The VM sets it to "Luau" and hosts often replace it: in seal it reads like "seal 0.9.0+0.730".

Primitives

noneLuwuflagged

none: none

The value that means "intentionally empty". It's falsy like nil and equal only to itself, but a table can store it: assigning none keeps the key and an array holding it has no hole. typeof(none) and tostring(none) both give "none". The none Primitive explains when to use it.