From 2a89c1e3ffc97e8f81b71cae552d3e9b24a7d440 Mon Sep 17 00:00:00 2001 From: PhoenixWhitefire Date: Sat, 9 May 2026 18:23:04 +0530 Subject: [PATCH 1/4] Propose integral number singletons --- docs/integral-number-singletons.md | 89 ++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 docs/integral-number-singletons.md diff --git a/docs/integral-number-singletons.md b/docs/integral-number-singletons.md new file mode 100644 index 000000000..045640616 --- /dev/null +++ b/docs/integral-number-singletons.md @@ -0,0 +1,89 @@ + +# Integral `number` singletons + +## Summary +Allow for singletons of the `number` primitive, similar to `boolean` (`true`/`false`). + +## Motivation +Programmers may want to use numeric constants as enumerations. Consider: + +```luau +type Deserialized = { + Items: { integer } +} + +local function convertFromV1ToV2(_: { string }): { integer } + -- ... +end + +local function deserialize(Serialized): Deserialized + local deserialized = {} + + if Serialized.Version == 1 then + deserialized.Items = convertFromV1ToV2(Serialized.Items) + elseif Serialized.Version == 2 then + deserialized.Items = Serialized.Items + else + error("unexpected version") + end + + return deserialized +end +``` + +As it stands, this code cannot be easily typechecked as the type of `Serialized` would have to be narrowed based on the numeric singleton `.Version`. +The desired type of `Serialized` would be: + +```luau +type SerializedStructure = { + Version: 1, + Items: { string } +} | { + Version: 2, + Items: { integer } +} +``` + +, however, this is currently inexpressible. `Version` would have to be left annotated as `number`, which prevents `deserialize` from typechecking +as the union of `Items` is not narrowed from `{ string } | { integer }`. + +Certain runtimes may expose platform-level APIs that use enumerations that are represented as `number`s. + +## Design + +Integral numeric literals valid in the value language (`0`, `0xF2`, `0b11001`, etc) will be made valid for use in the type language, similar to literals +such as `nil` or string literals like `"hello"`. They will be inferred as either their singleton or their supertype (`number`) with the same rules as +string singletons. +Literals with a decimal component are disallowed and raise a syntax error. + +Unions of the singletons will be narrowable through refinement similar to strings: + +```luau +local x: 1 | 0b10 | 0x3 = getX() + +if x == 1 or x == 2 then + local y: 1 | 2 = x -- No type error + local z: 3 = x -- Type error +end +``` + +They will be valid in the table indexer position: + +```luau +type T = { + [1 | 2]: string +} + +local t: T = {...} +print(t[1]) -- Ok, 1 <: 1 | 2 +print(t[3]) -- Type error, 3 Date: Sat, 9 May 2026 18:24:50 +0530 Subject: [PATCH 2/4] Add extra note to Motivation about tables with restricted indices --- docs/integral-number-singletons.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/integral-number-singletons.md b/docs/integral-number-singletons.md index 045640616..ab02eb6b0 100644 --- a/docs/integral-number-singletons.md +++ b/docs/integral-number-singletons.md @@ -49,6 +49,8 @@ as the union of `Items` is not narrowed from `{ string } | { integer }`. Certain runtimes may expose platform-level APIs that use enumerations that are represented as `number`s. +Programmers may want to annotate that a table only has a certain limited set of valid number indices. + ## Design Integral numeric literals valid in the value language (`0`, `0xF2`, `0b11001`, etc) will be made valid for use in the type language, similar to literals From 28ed790a2dbf0c7dfedbc283cf402f85d3cf1cdd Mon Sep 17 00:00:00 2001 From: PhoenixWhitefire <86601049+PhoenixWhitefire@users.noreply.github.com> Date: Wed, 13 May 2026 10:41:24 +0530 Subject: [PATCH 3/4] Heterogeneous arrays and minor edits --- ...number-singletons-heterogeneous-arrays.md} | 40 ++++++++++++++----- 1 file changed, 31 insertions(+), 9 deletions(-) rename docs/{integral-number-singletons.md => number-singletons-heterogeneous-arrays.md} (73%) diff --git a/docs/integral-number-singletons.md b/docs/number-singletons-heterogeneous-arrays.md similarity index 73% rename from docs/integral-number-singletons.md rename to docs/number-singletons-heterogeneous-arrays.md index ab02eb6b0..9335c0860 100644 --- a/docs/integral-number-singletons.md +++ b/docs/number-singletons-heterogeneous-arrays.md @@ -1,9 +1,11 @@ -# Integral `number` singletons +# Integral `number` singletons and heterogeneous arrays ## Summary Allow for singletons of the `number` primitive, similar to `boolean` (`true`/`false`). +Allow for them to be used like table properties to form heterogeneous arrays. + ## Motivation Programmers may want to use numeric constants as enumerations. Consider: @@ -51,6 +53,8 @@ Certain runtimes may expose platform-level APIs that use enumerations that are r Programmers may want to annotate that a table only has a certain limited set of valid number indices. +They may want to annotate that elements at different indices of a table have different types, opting for arrays instead of dictionaries for performance. + ## Design Integral numeric literals valid in the value language (`0`, `0xF2`, `0b11001`, etc) will be made valid for use in the type language, similar to literals @@ -69,23 +73,41 @@ if x == 1 or x == 2 then end ``` -They will be valid in the table indexer position: +They may be used to define a dependent type similar to table properties: ```luau type T = { - [1 | 2]: string + [1]: string, + [2]: vector } -local t: T = {...} -print(t[1]) -- Ok, 1 <: 1 | 2 -print(t[3]) -- Type error, 3 string +local z = x[2] --> vector + +local a: 1 | 2 = getIndex() +local w = x[a] --> string | vector ``` -Heterogeneous arrays are out of the scope of this RFC. +They intersect like table properties: + +```luau +type T = { + [1]: boolean +} + +type U = { + [2]: buffer +} + +type V = T & U --> { [1]: boolean, [2]: buffer } +``` ## Drawbacks * Increases complexity of the type system ## Alternatives -* Allow for decimals instead of restricting to integers -* Implement singletons for `integer`s +* Allow for decimals +* Singletons for `integer`s +* Intervals/bounds +* A type for NaN From 66af01bc118d3c4db3e74110fdfcc4a52d4e7747 Mon Sep 17 00:00:00 2001 From: PhoenixWhitefire <86601049+PhoenixWhitefire@users.noreply.github.com> Date: Sat, 16 May 2026 18:13:04 +0530 Subject: [PATCH 4/4] `{ T, U }` syntactic sugar for heterogeneous array types --- docs/number-singletons-heterogeneous-arrays.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/number-singletons-heterogeneous-arrays.md b/docs/number-singletons-heterogeneous-arrays.md index 9335c0860..05a270fc5 100644 --- a/docs/number-singletons-heterogeneous-arrays.md +++ b/docs/number-singletons-heterogeneous-arrays.md @@ -103,6 +103,8 @@ type U = { type V = T & U --> { [1]: boolean, [2]: buffer } ``` +As syntactic sugar, `{ T, U }` as a table type will be evaluated as `{ [1]: T, [2]: U }`. + ## Drawbacks * Increases complexity of the type system