Syntax

    Note that future versions of Lua extend the Lua 5.1 syntax with more features; Luau does support string literal extensions but does not support other 5.x additions; for details please refer to compatibility section.

    The rest of this document documents additional syntax used in Luau.

    Luau implements support for hexadecimal (), Unicode (\u) and \z escapes for string literals. This syntax follows :

    • \xAB inserts a character with the code 0xAB into the string
    • \u{ABC} inserts a UTF8 byte sequence that encodes U+0ABC character into the string (note that braces are mandatory)
    • \z at the end of the line inside a string literal ignores all following whitespace including newlines, which can be helpful for breaking long literals into multiple lines.

    Number literals

    In addition to basic integer and floating-point decimal numbers, Luau supports:

    • Hexadecimal integer literals, 0xABC or 0XABC
    • Binary integer literals, 0b01010101 or 0B01010101
    • Decimal separators in all integer literals, using _ for readability: 1_048_576, 0xFFFF_FFFF, 0b_0101_0101

    Note that Luau only has a single number type, a 64-bit IEEE754 double precision number (which can represent integers up to 2^53 exactly), and larger integer literals are stored with precision loss.

    In addition to break in all loops, Luau supports continue statement. Similar to break, continue must be the last statement in the block.

    Note that unlike break, continue is not a keyword. This is required to preserve backwards compatibility with existing code; so this is a continue statement:

    1. if x < 0 then
    2. continue
    3. end

    Whereas this is a function call:

    1. continue()
    2. end

    When used in repeat..until loops, continue can not skip the declaration of a local variable if that local variable is used in the loop condition; code like this is invalid and won’t compile:

    1. repeat
    2. do continue end
    3. local a = 5
    4. until a > 0

    Compound assignments

    Luau supports compound assignments with the following operators: +=, -=, , /=, %=, ^=, ..=. Just like regular assignments, compound assignments are statements, not expressions:

    1. -- this works
    2. a += 1
    3. -- this doesn't work
    4. print(a += 1)

    Compound assignments call the arithmetic metamethods (__add et al) and table indexing metamethods (__index and __newindex) as needed - for custom types no extra effort is necessary to support them.

    To support gradual typing, Luau supports optional type annotations for variables and functions, as well as declaring type aliases.

    Types can be declared for local variables, function arguments and function return types using : as a separator:

    1. function foo(x: number, y: string): boolean
    2. local k: string = y:rep(x)
    3. return k == "a"
    4. end

    In addition, the type of any expression can be overridden using a type cast :::

      There are several simple builtin types: any (represents inability of the type checker to reason about the type), nil, boolean, number, string and thread.

      Function types are specified using the arguments and return types, separated with ->:

      1. local foo: (number, string) -> boolean

      To return no values or more than one, you need to wrap the return type position with parentheses, and then list your types there.

      1. local no_returns: (number, string) -> ()
      2. local returns_boolean_and_string: (number, string) -> (boolean, string)
      3. function foo(x: number, y: number): (number, string)
      4. return x + y, tostring(x) .. tostring(y)
      5. end

      Note that function types are specified without the argument names in the examples above, but it’s also possible to specify the names (that are not semantically significant but can show up in documentation and autocomplete):

      Table types are specified using the table literal syntax, using : to separate keys from values:

      1. local object: { x: number, y: string }

      When the table consists of values keyed by numbers, it’s called an array-like table and has a special short-hand syntax, {T} (e.g. {string}).

      It’s common in Lua for function arguments or other values to store either a value of a given type or nil; this is represented as a union (number | nil), but can be specified using ? as a shorthand syntax (number?).

      In addition to declaring types for a given value, Luau supports declaring type aliases via type syntax:

      1. type Point = { x: number, y: number }
      2. type Array<T> = { [number]: T }
      3. type Something = typeof(string.gmatch("", "%d"))

      The right hand side of the type alias can be a type definition or a typeof expression; typeof expression doesn’t evaluate its argument at runtime.

      By default type aliases are local to the file they are declared in. To be able to use type aliases in other modules using require, they need to be exported:

      1. export type Point = { x: number, y: number }

      An exported type can be used in another module by prefixing its name with the require alias that you used to import the module.

      1. local M = require(Other.Module)

      For more information please refer to typechecking documentation.

      If-then-else expressions

      In addition to supporting standard if statements, Luau adds support for if expressions. Syntactically, if-then-else expressions look very similar to if statements. However instead of conditionally executing blocks of code, if expressions conditionally evaluate expressions and return the value produced as a result. Also, unlike if statements, if expressions do not terminate with the end keyword.

      Here is a simple example of an if-then-else expression:

      if-then-else expressions may occur in any place a regular expression is used. The if-then-else expression must match if <expr> then <expr> else <expr>; it can also contain an arbitrary number of elseif clauses, like if <expr> then <expr> elseif <expr> then <expr> else <expr>. Note that in either case, else is mandatory.

      Here’s is an example demonstrating elseif:

      1. local sign = if x < 0 then -1 elseif x > 0 then 1 else 0