From 6926e4ea02a5d87e0f2ab37a99b84941c5044353 Mon Sep 17 00:00:00 2001 From: ffrostfall <80861876+ffrostfall@users.noreply.github.com> Date: Wed, 6 Nov 2024 13:50:13 -0500 Subject: [PATCH 1/3] Add metatable-type-syntax.md --- docs/metatable-type-syntax.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 docs/metatable-type-syntax.md diff --git a/docs/metatable-type-syntax.md b/docs/metatable-type-syntax.md new file mode 100644 index 00000000..7e9debc0 --- /dev/null +++ b/docs/metatable-type-syntax.md @@ -0,0 +1,34 @@ +# Metatable Type Syntax + +## Summary + +Add unique syntax to allow for specifying the metatable of a type. + +## Motivation + +There is currently no expression for metatables within the type system, with the exception of hacks using `keyof`. That isn't great, because metatables are a commonly required feature for things like object-oriented programming. `typeof` is boilerplate which can likely be eliminated by allowing the expression of metatables through special syntax. + +## Design + +Introduce a context-sensitive `metatable` keyword which specifies that a table has a metatable. + +```lua +local class = {} +type Identity = { + field: string, + + metatable typeof(class) +} +``` + +## Alternatives + +`type T = { metatable {} }` could be too similar to field syntax. An argument could be made that `type T = { metatable: {} }` is too similar to metatable syntax. We could change the keyword to be `@metatable`, similar to how it is currently expressed as when converting a type to a string. However, this introduces a sigil, which increases cognitive load and harms readability. + +Do nothing, and instead rely on [metatable type functions](https://github.com/luau-lang/rfcs/pull/69) to achieve what this RFC proposes. However, relying purely on `setmetatable` for metatable type expression isn't ideal, as it involves more verbose syntax than what this RFC proposes. + +Do nothing, and live with the boilerpalte code required by the `typeof` solution. + +## Drawbacks + +Unique syntax always has the downside of an additional learning curve to the language. Context-sensitive keywords &sigils increase cognitive load when trying to read Luau, which isn't great. From 2d2e43238127c919dea42d470bf65de9d01fff27 Mon Sep 17 00:00:00 2001 From: ffrostfall <80861876+ffrostfall@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:53:47 -0500 Subject: [PATCH 2/3] Add linting metatable field to design --- docs/metatable-type-syntax.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/metatable-type-syntax.md b/docs/metatable-type-syntax.md index 7e9debc0..25d8bb53 100644 --- a/docs/metatable-type-syntax.md +++ b/docs/metatable-type-syntax.md @@ -21,6 +21,8 @@ type Identity = { } ``` +This could cause confusion with table properties named `metatable`. To combat this, a lint could be added which will warn upon setting table properties named `metatable`. To silence this lint, `["metatable"]` would need to be used instead. + ## Alternatives `type T = { metatable {} }` could be too similar to field syntax. An argument could be made that `type T = { metatable: {} }` is too similar to metatable syntax. We could change the keyword to be `@metatable`, similar to how it is currently expressed as when converting a type to a string. However, this introduces a sigil, which increases cognitive load and harms readability. From 4df0d8fea4e43b540b650670aa6a3ffb0c3265a5 Mon Sep 17 00:00:00 2001 From: ffrostfall <80861876+ffrostfall@users.noreply.github.com> Date: Wed, 6 Nov 2024 22:56:58 -0500 Subject: [PATCH 3/3] Reword alternatives --- docs/metatable-type-syntax.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/metatable-type-syntax.md b/docs/metatable-type-syntax.md index 25d8bb53..50cec92e 100644 --- a/docs/metatable-type-syntax.md +++ b/docs/metatable-type-syntax.md @@ -27,9 +27,9 @@ This could cause confusion with table properties named `metatable`. To combat th `type T = { metatable {} }` could be too similar to field syntax. An argument could be made that `type T = { metatable: {} }` is too similar to metatable syntax. We could change the keyword to be `@metatable`, similar to how it is currently expressed as when converting a type to a string. However, this introduces a sigil, which increases cognitive load and harms readability. -Do nothing, and instead rely on [metatable type functions](https://github.com/luau-lang/rfcs/pull/69) to achieve what this RFC proposes. However, relying purely on `setmetatable` for metatable type expression isn't ideal, as it involves more verbose syntax than what this RFC proposes. +We could instead rely on [metatable type functions](https://github.com/luau-lang/rfcs/pull/69) to achieve what this RFC proposes. However, relying purely on `setmetatable` for metatable type expression isn't ideal, as it involves more verbose syntax than what this RFC proposes. -Do nothing, and live with the boilerpalte code required by the `typeof` solution. +The final alternative is also to just do nothing, and live with the boilerpalte code required by the `typeof` solution. This doesn't add any new functionality. ## Drawbacks