teal-language / tl

The compiler for Teal, a typed dialect of Lua
MIT License
2.11k stars 109 forks source link

Properties/readonly fields #791

Open Frityet opened 3 weeks ago

Frityet commented 3 weeks ago

Some lua libraries have tables which have fields that can be read from, but not written to:

local tbl = setmetatable({ _data = { a = 4 } }, {
    __index = function(self, k) return self._data[k] end,
    __newindex = function(self, k)
        return error("Not allowed to set field "..k.." in table "..tostring(self))
    end
})

print(tbl.a) --ok
tbl.a = 4 --runtime error

Perhaps syntax such as

local record MyTable
   a<readonly>: integer
end

local tbl: MyTable = ...

print(tbl.a) --ok
tbl.a = 4 --compile time error

Could be introduced?

Frityet commented 3 weeks ago

Furthermore, as an extension, maybe full properties could be introduced?

local record MyRecord
    x<get=get_x, set=set_x>: integer
end

function MyRecord:get_x(): integer
    return 42
end

function MyRecord:set_x(val: integer)
    print("setting x to "..val)
end

local tbl: MyRecord = ...

print(tbl.x) --42
tbl.x = 1 -- setting x to 1

which would turn into

local MyRecord = {}

function MyRecord:get_x()
    return 42
end

function MyRecord:set_x(val)
    print("setting x to "..val)
end

local tbl: MyRecord = ...

print(tbl:get_x())
tbl:set_x(1)
lenscas commented 2 weeks ago

I am not a fan of full on properties. I don't like it when things that appear to be simply reading/writing to fields suddenly start to execute (potentially costly) functions.

Already have had plenty of times when things where much slower than expected because function calls where hiding in the code, pretending to be field accesses.

I do really like being able to say if a field is read-only though, and maybe set only as well.

hishamhm commented 2 weeks ago

Already have had plenty of times when things where much slower than expected because function calls where hiding in the code, pretending to be field accesses.

For better or worse, that is already a thing in Lua, because of metamethods.

I don't discount adding readonly fields in the future, though it can get either more complicated or less safe than what it seems initially, because of aliasing. One only needs to look at the constness rules from C and C++ to see that this can open quite a rabbit hole if one's not careful.

Having said that, I'm much less likely to add properties. The use-case suggested here sounds like a task for something like a compile-time metamethod (which is a more general concept than getter/setter properties). That would be more appealing to me, but I have no immediate plans to work on that either.