IppClub / IppClub/YueScript

[Feature request] Computed properties

Open
#219 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Lua
Stars
613
Forks
45
PR merge metrics
No merged PRs in 30d

Description

Some languages allow defining methods that can be used like object attributes. For example, in JavaScript:

class Foo {
    get x() {
        console.log("Getting x");
        // In JS, member names starting wtih `#` are private and cannot
        // be accessed from the outside by any means.
        return this.#x;
    }

    set x(value) {
        console.log("Setting x to", value);
        this.#x = value;
    }
}

I would appreciate it if YueScript could do something similar. It could look something like this:

import "yue"

class Foo
    get x: () =>
        print("Getting x")
        @_x

    set x: (value) =>
        io.write("Setting x to ")
        yue.p(value)
        @_x = value

The output could then be something like this:

local yue = require("yue")
local Foo
local _class_0
local _base_0 = {}
local _index_0 = rawget(_base_0, "__index")
if _index_0 == nil then
	_index_0 = _base_0
end
if type(_index_0) == "table" then
	local _index_1 = _index_0
	_index_0 = function(_, key)
		return _index_1[key]
	end
end
local _newindex_0 = rawget(_base_0, "__newindex")
if _newindex_0 == nil then
	_newindex_0 = rawset
end
rawset(_base_0, "__index", function(self, key)
	local properties = rawget(_class_0, "__properties")
	local property = rawget(properties, key)
	if property ~= nil then
		local getter = rawget(property, "get")
		if getter ~= nil then
			return getter(self)
		end
	end
	return _index_0(self, key)
end)
rawset(_base_0, "__newindex", function(self, key, value)
	local properties = rawget(_class_0, "__properties")
	local property = rawget(properties, key)
	if property ~= nil then
		local setter = rawget(property, "set")
		if setter ~= nil then
			return setter(self, value)
		end
	end
	return _newindex_0(self, key, value)
end)
_class_0 = setmetatable({
    __init = function() end,
    __base = _base_0,
    __name = "Foo",
    __properties = {
        x = {
            get = function(self)
                print("Getting x")
                return self._x
            end,
            set = function(self, value)
                io.write("Setting x to ")
                yue.p(value)
                self._x = value
                return value
            end
        }
    }
}, {
    __index = _base_0,
    __call = function(cls, ...)
        local _self_0 = setmetatable({}, _base_0)
        cls.__init(_self_0, ...)
        return _self_0
    end
})
_base_0.__class = _class_0
Foo = _class_0
return _class_0

And to test it:

print(Foo, Foo.x)
local instance = Foo()
print(instance, instance.x)
instance.x = "Test"
print(instance.x)

Its output:

table: 0x12341234	nil
Getting x
table: 0xdeadbeef	nil
Setting x to "Test"
Getting x
Test

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

No repository file or test is named. Start by reviewing the class compilation path and the generated Lua metatable example in the issue, then define how getter and setter properties should interact with existing class behavior. Done means the shown YueScript example compiles and produces the described access and assignment results.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.