diff --git a/docs/_posts/2022-03-31-luau-recap-march-2022.md b/docs/_posts/2022-03-31-luau-recap-march-2022.md index 13714d01..901eae63 100644 --- a/docs/_posts/2022-03-31-luau-recap-march-2022.md +++ b/docs/_posts/2022-03-31-luau-recap-march-2022.md @@ -7,19 +7,94 @@ Luau is our new language that you can read more about at [https://luau-lang.org] [Cross-posted to the [Roblox Developer Forum](https://devforum.roblox.com/t/luau-recap-march-2022/).] -## Tagged unions +## 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) +else + -- 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 is called *width subtyping* (it allows tables to get *wider*, that is 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. - * Less crashing due to mutating types which shouldn't be. - * Fix a bug that could cause two incompatible copies of the same class to be created. - * Cope better with cyclic metatable types. + * 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 + * Add support for `table.clone`. - * Better error messages. - * Fix a bug that confused union and intersection types of table properties. ## Debugger improvements @@ -27,11 +102,8 @@ Luau is our new language that you can read more about at [https://luau-lang.org] ## 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. -## Thanks - -A special thanks to all the fine folks who contributed PRs this month! - -* [ProBaturay](https://github.com/ProBaturay)