From 1f6c57b2605e7ff2990d9c0bf431c35dbf73a0d2 Mon Sep 17 00:00:00 2001 From: SolarScuffle-Bot <93509782+SolarScuffle-Bot@users.noreply.github.com> Date: Thu, 4 Jan 2024 18:53:34 -1000 Subject: [PATCH] Update polymorphic-table-types.md --- docs/polymorphic-table-types.md | 55 +++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/docs/polymorphic-table-types.md b/docs/polymorphic-table-types.md index e8c8312..bfa72c5 100644 --- a/docs/polymorphic-table-types.md +++ b/docs/polymorphic-table-types.md @@ -94,6 +94,8 @@ We've lost our type information of `a` and `b` in the last table step! We propose naturally extending this type-mapping capability to tables in the backwards-compatible form `{ [F]: G }`. We recycle our familiar syntax of polymorphic functions and use them in a very similar fashion. If one understands polymorphic functions, they will understand this as well. It is backwards compatible as it is currently invalid syntax. +### General Accessor Solution + To rewrite our previous code examples using the new type: ```lua @@ -107,6 +109,8 @@ type A = { [F]: G } type B = (F) -> G ``` +### Specific Accessor Solution + Back to the ECS example, we change the type of `components` to be what it should have been all along: ```lua @@ -122,17 +126,56 @@ local b = components[B] And perfect intellisense is now achieved without a single typecast or getter (per component). It was simple too, encouraging the simplest solution in the process. -We believe that this implementation is a natural step in the direction towards a fuller Luau type-system, as it already has a functional cousin and practical use-cases. Concerns with api coherency, stylistic coherency, learning curve, acceptance, and more are all already answered with polymorphic functions. If you want to understand the behavior of a polymorphic table, simply look to the behavior of polymorphic functions as they will have the exact same properties. +We believe that this implementation is a natural step in the direction towards a fuller Luau type-system, as it already has a functional cousin and practical use-cases. Concerns with api coherency, stylistic coherency, learning curve, acceptance, and more already answered with polymorphic functions. If you want to understand the behavior of a polymorphic table, simply look to the behavior of polymorphic functions as they will have the exact same properties. `function` $\cong$ `table` +### Inferability +In order for T to be inferable, it must appear in the argument of a function or key of table. If it is not present, the mapped type is left as a free-type, denoted `a`, `b`, ... + ```lua -(any) -> T implies T = never -{ [any]: T } implies T = never +-- T is inferable +(any) -> (any) -> ... -> (T) -> G + +-- T is inferable +{ [any]: { [any]: ... { [T]: G } } } + +-- T = a +(any) -> T + +-- T = a +{ [any]: T } ``` + +### Indexers +At the time of this RFC, table types only support a single accessor excluding string keys. This is as complex as a table may be: + ```lua -(any) -> (T) -> G implies T is inferable -{ [any]: { [T]: G } } implies T is inferable + { + string1: F, + string2: G, + ..., + [H]: I, +} +``` + +However, if this is to change, the expected behavior of multiple indexers is: + +```lua + { + string1: F, -- Precedence over indexers + + [number]: boolean, -- Precedence over generic indexers, a generic indexer may not be a specific indexer + + -- U = a, ignored in favor of later generic indexer, warning about multiple generic indexers + [T]: U, + + -- T = a, ignored in favor of later generic indexer, warning about multiple generic indexers + [U]: T, + + -- V is inferable, used because last generic indexer, V ~= number because specific indexer + [V]: V, +} ``` ## Drawbacks @@ -143,7 +186,7 @@ There is little to no concern with feature-creep, as it is a necessity to achiev This feature does complicate the type solver and language, however it is done in the best case scenario as an opt-in complication only by those that need it, typically by tool maintainers and almost never typical users who are not well versed with luau types. -Native code generation will most likely not be able to optimize any more than it would `{ [any]: any }`. +Native code generation will most likely not be able to optimize tables of this type any more than it would `{ [any]: any }`. ## Alternatives