--- layout: single title: "Luau Recap: March 2022" --- Luau is our new language that you can read more about at [https://luau-lang.org](https://luau-lang.org). [Cross-posted to the [Roblox Developer Forum](https://devforum.roblox.com/t/luau-recap-march-2022/).] ## Singleton types We added support for singleton types! These allow you to use string or boolean literals in types. These types are only inhabited by the literal, for example if a variable `x` has type `"foo"`, then `x == "foo"` is guaranteed to be true. Singleton types are particularly useful when combined with union types, for example: ```lua type Animals = "Dog" | "Cat" | "Bird" ``` or: ```lua type Falsey = false | nil ``` In particular, singleton types play well with unions of tables, allowing tagged unions (also known as discriminated unions): ```lua type Ok = { type: "ok", value: T } type Err = { type: "error", error: E } type Result = Ok | Err local result: Result = ... if result.type == "ok" then -- result :: Ok print(result.value) elseif result.type == "error" then -- result :: Err error(result.error) end ``` The RFC for singleton types is https://github.com/Roblox/luau/blob/master/rfcs/syntax-singleton-types.md ## Width subtyping A common idiom for programming with tables is to provide a public interface type, but to keep some of the concrete implementation private, for example: ```lua type Interface = { name: string, } type Concrete = { name: string, id: number, } ``` Within a module, a developer might use the concrete type, but export functions using the interface type: ```lua local x: Concrete = { name = "foo", id = 123, } local function get(): Interface return x end ``` Previously examples like this did not typecheck but now they do! This language feature is called *width subtyping* (it allows tables to get *wider*, that is to have more properties). The RFC for width subtyping is https://github.com/Roblox/luau/blob/master/rfcs/sealed-table-subtyping.md ## Typechecking improvements * Generic function type inference now works the same for generic types and generic type packs. * We improved some error messages. * There are now fewer crashes (hopefully none!) due to mutating types inside the Luau typechecker. * We fixed a bug that could cause two incompatible copies of the same class to be created. * Luau now copes better with cyclic metatable types (it gives a type error rather than hanging). * Fixed a case where types are not properly bound to all of the subtype when the subtype is a union. * We fixed a bug that confused union and intersection types of table properties. * Functions declared as `function f(x : any)` can now be called as `f()` without a type error. ## API improvements * Implement `table.clone` which takes a table and returns a new table that has the same keys/values/metatable. The cloning is shallow - if some keys refer to tables that need to be cloned, that can be done manually by modifying the resulting table. ## Debugger improvements * Use the property name as the name of methods in the debugger. ## Performance improvements * Optimize table rehashing (~15% faster dictionary table resize on average) * Improve performance of freeing tables (~5% lift on some GC benchmarks) * Improve gathering performance metrics for GC. * Reduce stack memory reallocation.