From c7b66aecf595f75a3e049d85860571bfef38c982 Mon Sep 17 00:00:00 2001 From: Vyacheslav Egorov Date: Fri, 6 Aug 2021 19:37:20 +0300 Subject: [PATCH] RFC: Default type alias type parameters --- ...ntax-default-type-alias-type-parameters.md | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 rfcs/syntax-default-type-alias-type-parameters.md diff --git a/rfcs/syntax-default-type-alias-type-parameters.md b/rfcs/syntax-default-type-alias-type-parameters.md new file mode 100644 index 00000000..7882df54 --- /dev/null +++ b/rfcs/syntax-default-type-alias-type-parameters.md @@ -0,0 +1,73 @@ +# Default type alias type parameters + +## Summary + +Introduce syntax to provide default type values inside the type alias type parameter list. + +## Motivation + +Luau has support for type parameters for type aliases and functions. +In languages with similar features like C++ and TypeScript, it is possible to specify default values and users with experience in those languages would like to use that in Luau. + +As an example, this feature can be used to define a equality comparator function type that by default accepts a single type argument and assigns the same type to the second argument, but it's still possible to specify both type arguments: +```lua +type Eq = (l: T, r: U) -> boolean + +local a: Eq = ... +local b: Eq = ... +``` + +While previous examples reference type parameters from the same list, it is also possible to specify concrete types: +```lua +type StrArray = {arr: {T}, locked: boolean} + +local a: StrArray = ... +local b: StrArray = ... +``` + +Generic functions in Luau also have a type parameter list, but it's not possible to specify type arguments at the call site and because of that, default type argument values for generic functions are not proposed. + +## Design + +If a default type argument value is assigned, following type parameters (on the right) must also have default type argument values. +```lua +type A = ... -- not allowed +``` + +Default type argument values can reference type parameters which were defined earlier (to the left): +```lua +type A = ...-- ok + +type A = ... -- not allowed +``` + +Default type arguments are not allowed for type pack parameters. + +--- + +Syntax for type alias type argument is extended as follows: + +```typearg ::= Name [`=' typeannotation]``` + +Instead of storing a simple array of names in AstStatTypeAlias, we will store an array of structs containing the name and an optional default type value. + +When type alias is referenced, missing type parameters are replaced with default type values, if they are available. + +If all type parameters have a default type value, it is now possible to reference that without providing a type parameter list: +```lua +type All = ... + +local a: All -- ok +local b: All<> -- not allowed +``` + +If type is exported from a module, default type parameter values will still be available when module is imported. + +## Drawbacks + +Previously, it was possible to reference type alias without type arguments inside that alias (recursive types). +We disallow that now, but if we decide to return that, there will be an ambiguity if all type parameters have a default value. + +## Alternatives + +We could use `:` instead of `=` to define default type parameter values.