mirror of
https://github.com/luau-lang/rfcs.git
synced 2025-05-04 10:43:48 +01:00
Update support-for-type-packs-in-user-defined-type-functions.md
Major change: Separated packs from the type userdata since packs are not types.
This commit is contained in:
parent
e56c2b4213
commit
94304b2e57
1 changed files with 34 additions and 29 deletions
|
@ -13,16 +13,16 @@ This limits the usage for packs as they are used often in the language, and thei
|
||||||
|
|
||||||
## Design
|
## Design
|
||||||
|
|
||||||
We introduce a new runtime type called `pack` to extend the support of type packs within the type runtime.
|
We introduce a new userdata called `pack` alongside `type` to extend the support of type packs within the type runtime.
|
||||||
|
|
||||||
Packs will have a `kind` property that specifies the kind of the pack. A pack can either be a `list` kind or a `variadic` kind.
|
`pack` instances will have a `kind` property that specifies the kind of the pack. A `pack` can either be of a `literal` kind or of a `variadic` kind.
|
||||||
|
|
||||||
For example, consider a variadic type pack (e.g `...number`), in the new pack type, it will be represented as a `pack` with a `variadic` kind.
|
For example, consider a variadic type pack (e.g `...number`), in the new pack type, it will be represented as a `pack` with a `variadic` kind.
|
||||||
Or for a normal type pack such as `(number, string)`, it will be represented as a `pack` with a `list` kind.
|
Or for a normal type pack such as `(number, string)`, it will be represented as a `pack` with a `literal` kind.
|
||||||
|
|
||||||
`list` kind of packs will be able to contain other packs, or types more than one, whereas `variadic` type of packs will only contain *one* type.
|
`literal` packs will be able to contain other packs, or types more than one, whereas `variadic` kind of packs will only contain *one* type.
|
||||||
|
|
||||||
The user will be able to obtain the types within `pack`s using the `:unpack()` method, this method will return a table containing all the types or type packs within the pack.
|
The user will be able to obtain the `type`s within `pack`s using the `:unpack()` method, this method will return a table containing all the `type`s or `pack`s within the `pack`.
|
||||||
In `variadic` kind of `pack`s, `:unpack()` will only return a table with one element. This is because variadic packs are essentially many elements of the same type.
|
In `variadic` kind of `pack`s, `:unpack()` will only return a table with one element. This is because variadic packs are essentially many elements of the same type.
|
||||||
|
|
||||||
In user-defined type functions, type packs can be created by providing types or type packs that will be included within the pack. A pack will also be able to contain other packs, even packs of different kinds.
|
In user-defined type functions, type packs can be created by providing types or type packs that will be included within the pack. A pack will also be able to contain other packs, even packs of different kinds.
|
||||||
|
@ -32,10 +32,9 @@ In user-defined type functions, type packs can be created by providing types or
|
||||||
Creating a type function that accepts type packs:
|
Creating a type function that accepts type packs:
|
||||||
|
|
||||||
```luau
|
```luau
|
||||||
type function f(arg: type)
|
type function f(arg: pack)
|
||||||
if not arg:is("pack") then error("The given argument is not a type pack!") end
|
if typeof(arg) ~= "pack" then error("The given argument is not a type pack!") end
|
||||||
local unpacked = arg:unpack() -- {string, number}
|
local unpacked = arg:unpack() -- {string, number}
|
||||||
print(unpacked)
|
|
||||||
end
|
end
|
||||||
type a = f<(string, number)>
|
type a = f<(string, number)>
|
||||||
```
|
```
|
||||||
|
@ -44,8 +43,9 @@ Creating a type function that returns a function with a type pack:
|
||||||
|
|
||||||
```luau
|
```luau
|
||||||
type function f()
|
type function f()
|
||||||
local newListPack = types.pack({types.string, types.number})
|
local newPack = types.pack({types.string, types.number}) -- (string, number)
|
||||||
local newVariadicPack = types.pack({types.any}, true)
|
local newVariadicPack = types.pack({types.any}, true) -- ...any
|
||||||
|
|
||||||
local newfunc = types.newfunction()
|
local newfunc = types.newfunction()
|
||||||
newfunc:setparameters({newPack}, newVariadicPack)
|
newfunc:setparameters({newPack}, newVariadicPack)
|
||||||
newfunc:setreturns({newPack}, newVariadicPack)
|
newfunc:setreturns({newPack}, newVariadicPack)
|
||||||
|
@ -58,7 +58,7 @@ The pack type will also enable generic type packs to be provided to type functio
|
||||||
Generic type pack arguments will pass the given type pack to the type function.
|
Generic type pack arguments will pass the given type pack to the type function.
|
||||||
|
|
||||||
```luau
|
```luau
|
||||||
type function createCallback(args: type, returns: type) -- args will be a list pack, returns will be a variadic pack.
|
type function createCallback(args: pack, returns: pack) -- args will be a literal pack, returns will be a variadic pack.
|
||||||
local newTable = types.newtable()
|
local newTable = types.newtable()
|
||||||
local newfunc = types.newfunction()
|
local newfunc = types.newfunction()
|
||||||
newfunc:setparameters({args})
|
newfunc:setparameters({args})
|
||||||
|
@ -74,35 +74,40 @@ If variadic type functions were to be implemented, type packs could be retrieved
|
||||||
|
|
||||||
```luau
|
```luau
|
||||||
type function f(...)
|
type function f(...)
|
||||||
local packed = {...} -- {type}
|
local packed = {...} -- {pack}
|
||||||
local firstPack = packed[1] -- type.kind: list
|
local firstPack = packed[1] -- pack.kind: literal
|
||||||
local secondPack = packed[2] -- type.kind: variadic
|
local secondPack = packed[2] -- pack.kind: variadic
|
||||||
end
|
end
|
||||||
type a = f<(string, number), ...number>
|
type a = f<(string, number), ...number>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Updates to the types library and type userdata
|
Evaluating `typeof(...)` on a `pack` userdata will give the string `"pack"`.
|
||||||
|
|
||||||
|
```luau
|
||||||
|
type function f(arg: pack)
|
||||||
|
print(typeof(arg)) -- "pack"
|
||||||
|
end
|
||||||
|
type a = f<(string, number)>
|
||||||
|
```
|
||||||
|
|
||||||
|
## New pack userdata
|
||||||
|
|
||||||
|
### `pack` Instance
|
||||||
|
|
||||||
|
| New/Update | Instance Properties & Methods | Type | Description |
|
||||||
|
| ------------- | ------------- | ------------- | ------------- |
|
||||||
|
| New | `kind` | `"literal" \| "variadic"` | indicates the kind of the `pack`. |
|
||||||
|
| New | `unpack()` | `{pack \| type}` | returns the `type`s contained within the `pack`, returns only one element if `kind` is `variadic`. |
|
||||||
|
|
||||||
|
## Updates to the types library and the type userdata
|
||||||
|
|
||||||
### `types` Library
|
### `types` Library
|
||||||
|
|
||||||
| New/Update | Library Functions | Return Type | Description |
|
| New/Update | Library Functions | Return Type | Description |
|
||||||
| ------------- | ------------- | ------------- | ------------- |
|
| ------------- | ------------- | ------------- | ------------- |
|
||||||
| New | `pack(types: {type} isvariadic: boolean?)` | `type` | returns an immutable instance of a type pack; when `isvariadic` is true, `types` table can only have one type. |
|
| New | `pack(args: {pack \| type}, isvariadic: boolean?)` | `pack` | returns an immutable instance of a type pack; when `isvariadic` is true, `args` table can only have one `type`. |
|
||||||
| Update | `newfunction(parameters: { head: {type}?, tail: type? }, returns: { head: {type}?, tail: type? }, generics: {type}?)` | `type` | `tail` arguments can now accept variadic packs.
|
| Update | `newfunction(parameters: { head: {type}?, tail: type? }, returns: { head: {type}?, tail: type? }, generics: {type}?)` | `type` | `tail` arguments can now accept variadic packs.
|
||||||
|
|
||||||
### `type` Instance
|
|
||||||
|
|
||||||
| New/Update | Instance Properties | Type | Description |
|
|
||||||
| ------------- | ------------- | ------------- | ------------- |
|
|
||||||
| Update | `tag` | `"nil" \| "unknown" \| "never" \| "any" \| "boolean" \| "number" \| "string" \| "singleton" \| "negation" \| "union" \| "intersection" \| "table" \| "function" \| "class" \| "thread" \| "buffer" \| "generic" \| "pack"` | Added `pack` as a possible tag |
|
|
||||||
|
|
||||||
#### Pack `type` instance
|
|
||||||
|
|
||||||
| New/Update | Instance Methods | Type | Description |
|
|
||||||
| ------------- | ------------- | ------------- | ------------- |
|
|
||||||
| New | `kind` | `"list" \| "variadic"` | indicates the kind of the pack. |
|
|
||||||
| New | `unpack()` | `{type}` | returns the types contained within the pack, returns only one element if `kind` is `variadic`. |
|
|
||||||
|
|
||||||
#### Function `type` instance
|
#### Function `type` instance
|
||||||
|
|
||||||
| New/Update | Instance Methods | Return Type | Description |
|
| New/Update | Instance Methods | Return Type | Description |
|
||||||
|
|
Loading…
Add table
Reference in a new issue