Yuescript
Yuescript copied to clipboard
Fill operator
In JavaScript, the fill operator is a very handy thing:
const template = {
foo: "Hello",
bar: "World",
baz: "!",
};
const specialized = {
...template,
bar: "Bob"
};
Since ... in lua is used for unpacking variable arguments and therefore can't be used here, I'd like to suggest that .. be used as the fill operator only when it comes before an identifier in a table:
str1 = "Hello"
str2 = "world"
str3 = str1.." "..str2.."!" -- Concat operator is used here
template = {
foo: "Hello",
bar: "World",
baz: "!",
}
specialized = {
..template, -- Fill operator is used here
foo: "Goodbye",
..template, -- Fill operator is used here
bar: "Bob",
baz: template.baz.."?", -- Concat operator is used here
}
-- specialized = { foo: "Hello", bar: "Bob", baz: "" }
Compilation for this might require a utility function to be baked in:
_G["月"] = {
fill = function(from, to)
local mt = getmetatable(from)
if mt ~= nil then
-- Checks for a __fill metamethod, in case classes or other special tables should be handled differently.
if type(mt.__fill) == "function" then
mt.__fill(from, to)
return
end
end
for key, value in next, from do to[key] = value end
end,
}
local template = {
foo = "Hello",
bar = "World",
baz = "!",
}
local specialized
do
local o = { }
_G["月"].fill(template, o)
o.foo = "Goodbye"
_G["月"].fill(template, o)
o.bar = "Bob"
o.baz = template.baz.."?"
specialized = o
end
Of course, the utility function could be inlined, but I feel like thats probably a waste.
Yuescript is more like a macro system for Lua to introduce more syntax sugar and compiles to Lua. Since the table filling function is not implemented in Lua compiler itself, the Yuescript compiler has to add some inlined Lua codes to finish the job. In this way, for different code files in the same project, the utility function will be duplicated.
There is a Coffeescript dialect named Livescript which adds many similar features for new syntax by inlining many Javascript codes or functions, but Livescript provides function to merge multiple source files into one source file so that the duplicated inline codes could be eliminated. So I think it is currently not a good idea for Yuescript to implement features like this.
I think thats true-- this would be better to implement if (when?) YueScript can compile several files together
latest yuescript version workaround (only index)
template = {
foo: "Hello",
bar: "World",
"!"
}
specialized = {
index#: template, -- "fill" operator workaround (uses metatable __index)
bar: "Bob"
}
print specialized.foo .. " " .. specialized.bar .. specialized[1] --> "Hello Bob!"
Add an implementation for the Fill operator, works on both array table and hash table.
template = {
foo: "Hello"
bar: "World"
"!"
}
specialized = {
"a", "b", "c"
...template
bar: "Bob"
}
Compile to:
local template = {
foo = "Hello",
bar = "World",
"!"
}
local specialized
do
local _tab_0 = {
"a",
"b",
"c"
}
local _idx_0 = 1
for _key_0, _value_0 in pairs(template) do
if _idx_0 == _key_0 then
_tab_0[#_tab_0 + 1] = _value_0
_idx_0 = _idx_0 + 1
else
_tab_0[_key_0] = _value_0
end
end
_tab_0.bar = "Bob"
specialized = _tab_0
end
Get result:
specialized = {
[1] = "a"
[2] = "b"
[3] = "c"
[4] = "!"
[foo] = "Hello"
[bar] = "Bob"
}