mirror of
https://github.com/luau-lang/rfcs.git
synced 2025-04-05 19:11:00 +01:00
Create user_defineable_self_namecall_type.md
This commit is contained in:
parent
b57bf48689
commit
75464d5752
1 changed files with 169 additions and 0 deletions
169
docs/user_defineable_self_namecall_type.md
Normal file
169
docs/user_defineable_self_namecall_type.md
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
# User Defineable ``self`` Namecall Type
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
|
||||||
|
The aim is to allow simple definition of ``self`` when defining functions with ``:``
|
||||||
|
|
||||||
|
```lua
|
||||||
|
function Class:TestMethod()
|
||||||
|
self.@1
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
**Autocompletion is the motivation**.
|
||||||
|
|
||||||
|
See the "Alternatives" section to understand the motivation as well.
|
||||||
|
|
||||||
|
The point is to be able to define ``self`` in **namecall** defined functions as well.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Design
|
||||||
|
Yet to be found.
|
||||||
|
|
||||||
|
|
||||||
|
## Drawbacks
|
||||||
|
|
||||||
|
Wouldn't see one for now.
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
### Best Alternative
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local Class = {}
|
||||||
|
Class.__index = Class
|
||||||
|
|
||||||
|
|
||||||
|
function Class.new()
|
||||||
|
local obj = setmetatable({}, Class)
|
||||||
|
|
||||||
|
obj.Value1 = 1
|
||||||
|
obj.Value2 = 2
|
||||||
|
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
type ClassObject = typeof(Class.new())
|
||||||
|
|
||||||
|
|
||||||
|
function Class:TestMethod()
|
||||||
|
self = self :: ClassObject
|
||||||
|
|
||||||
|
-- Now "self" has Value1 and Value2
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
This ``self = self :: ClassObject`` is the easiest way that I know about. Based on my analysis. The default compile optimization mode will not count that part into compilation.
|
||||||
|
|
||||||
|
Which is good, which means that this current way doesn't have any impact in anything. **But it is repetitive**.
|
||||||
|
|
||||||
|
However, one will be able to index ``Class:@1`` to **differentiate** methods defined by ``:``.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Second Alternative
|
||||||
|
```lua
|
||||||
|
local Class = {}
|
||||||
|
Class.__index = Class
|
||||||
|
|
||||||
|
|
||||||
|
function Class.new()
|
||||||
|
local obj = setmetatable({}, Class)
|
||||||
|
|
||||||
|
obj.Value1 = 1
|
||||||
|
obj.Value2 = 2
|
||||||
|
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
type ClassObject = typeof(Class.new())
|
||||||
|
|
||||||
|
|
||||||
|
function Class.TestMethod(self: ClassObject)
|
||||||
|
-- "self" has Value1 and Value2
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
**This is still repetitive**
|
||||||
|
|
||||||
|
The bigger issue is that this is not autocompletion friendly.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local Test = Class.new()
|
||||||
|
|
||||||
|
Test:@1
|
||||||
|
```
|
||||||
|
This will show it in the autocomplete. But that's not the issue.
|
||||||
|
|
||||||
|
The issue is when you use the pure Class table and index it with ``:``
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local Class = {}
|
||||||
|
Class.__index = Class
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function Class.new()
|
||||||
|
local obj = setmetatable({}, Class)
|
||||||
|
|
||||||
|
obj.Value1 = 1
|
||||||
|
obj.Value2 = 2
|
||||||
|
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
type ClassObject = typeof(Class.new())
|
||||||
|
|
||||||
|
function Class.TestMethod(self: (typeof(Class) & typeof(ClassObject)))
|
||||||
|
-- "self" has Value1 and Value2
|
||||||
|
end
|
||||||
|
|
||||||
|
Class:@1
|
||||||
|
```
|
||||||
|
|
||||||
|
Notice how ``ClassObject`` is not resolved at that time.
|
||||||
|
|
||||||
|
If one wanted to do ``Class:@1`` to filter out all namecall methods in their code, without creating a constructor. They simply can't.
|
||||||
|
|
||||||
|
But this is a **metatable** in a class-construction context. Even Lua designs these OOP functions like that https://www.lua.org/pil/16.2.html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Strict Type Alternative
|
||||||
|
This is an alternative that I captured off from **react-lua**.
|
||||||
|
|
||||||
|
```lua
|
||||||
|
local Class = {} :: {
|
||||||
|
-- This is the thing that defines self
|
||||||
|
[string]: (self: string) -> any
|
||||||
|
}
|
||||||
|
Class.__index = Class
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function Class.new()
|
||||||
|
local obj = setmetatable({}, Class)
|
||||||
|
|
||||||
|
obj.Value1 = 1
|
||||||
|
obj.Value2 = 2
|
||||||
|
|
||||||
|
return obj
|
||||||
|
end
|
||||||
|
|
||||||
|
type ClassObject = typeof(Class.new())
|
||||||
|
|
||||||
|
|
||||||
|
function Class:TestMethod()
|
||||||
|
self.@1
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
``self`` is now a ``string``. By defining ``[string]`` the automatic type resolver won't automatically put the actual things defined in the code into that table as well. That's why it isn't that good, but it's very smart.
|
Loading…
Add table
Reference in a new issue