This is a pet project of mine, a sort of thought experiment about what would fit into lua without breaking convention (except the minimalist convention lol). I think many of the elements could combine into a new language, but there is no current plan to do that.
- Make lua more pleasent
- Maintain lua conventions
- Stay intuitive to a lua programmer
- Avoid breaking most lua code, though will add keywords
- Improve signal to noise, but not too dense
- Have fun
- Bikeshedding syntax
- Investigating edge cases (for now)
- Making things familiar to programmers of X language
- Importing OOP or FP concepts directly
- ‘magic’ or heavily abstracted features
This URL has some patches and documentation, which are later linked to in this file as examples of what has been made. http://lua-users.org/wiki/LuaPowerPatches
I am also examining moonscript for ideas: https://moonscript.org/reference
local x, y = do
local a,b = 10,20
give a * b, a + b
end
-- Turns into (roughly)
local x, y
do
local a,b = 10,20
x,y = a * b, a + b
end
local t = if cond then
give 10
else
give 20
end
-- Turns into (roughly)
local t
if cond then
t=10
else
t=20
end
loop expressions introduce the new form break x
which exits the loop and
returns value x
from the loop.
-- For expression --
local i,v = for i,v in ipairs(t) do
if v == 8 then
break i,v
end
end
-- Functions like
local i,v
for _i,_v in ipairs(t) do
if _v == 8 then
i,v = _i,_v
end
end
Similar to ‘for’, but is an expression that operates on a temporary table which is returned to lhs.
In moonscript: https://moonscript.org/reference/#the-language/comprehensions
local multiples_of_2 = through i = 1,10 do
give i * 2
end
-- Gives {2,4,6,8,10,12}
local my_list = through i, v in {1,2,3,4,5,9} do
if v ~= 4 then
give v * 2
end
end
-- Gives {2,4,6,10,18}
local tab = {{1,0,1},{2,0,2},{3,0,3}}
local doubled = through _,v in tab do
give through _,w in v do
if w > 0 then
give w * 2
end
end
end
-- Gives {{2,2},{4,4},{6,6}}
local backwards_map = through k,v in {a=10, b=20, c=30} do
give v=k
end
-- Gives {[10]='a', [20]='b', [30]='c'}
This interacts nicely with the expression extensions, allowing for flexible constant initialization.
const x=2, <mut>y=3, <close>z = 4
-- Turns into
local <const> x=2, y=3, <close> z = 4
This patch gives a default way of handling ‘for’ http://lua-users.org/files/wiki_insecure/power_patches/5.3/jh-lua-iter-5.3.1.patch
for x in y do ... end
-- Turns into (roughly)
local function iter (t)
local mt = getmetatable(t)
if type(t)=='function' or mt.__call then
return t
else
if mt.__iter then
return mt.__iter(t)
else
return ipairs(t)
end
end
end
for x in iter(y) do ... end
toliteral could serialize to a lua expression to a functional piece of code.
assert(toliteral(true) == 'true')
assert(toliteral('hello') == '"hello"')
assert(toliteral(100) == '100')
This could be used in debug prints.
For tables, toliteral({'hello', a='b'})
could turn into {[1] = 'hello', ['a'] = 'b'}
or
similar.
http://lua-users.org/files/wiki_insecure/power_patches/5.2/unpack-5.2.2.patch
-- This already works:
local a, b = unpack{10, 20}
-- This patch allows for this:
local a, b in {a=10, b=20}
-- Which would mean:
local t = {a=10, b=10}
local a, b = t.a, t.b
I like this, but I want to extend it so that local vars can be renamed to
something other than a field of the expression. local {a, c=b} in {a=10, b=20}
or something along those lines.
Allow type checking for function arguments. If arguments don’t match the provided type(s), throw an error.
Lua should make sure the default value matches the type specified in the type guard, if applicable.
function (:number: x, :table|number:y, :string:z = 'ree', :!nil:zz)
...
end
-- Turns into (roughly)
function (x,y,z,zz)
assert(type(x)=='number')
assert(type(y)=='table' or type(y)=='number')
z = z or 'ree'
assert(type(z)=='string')
assert(not type(zz)=='nil')
...
end
Possible type specifiers:
table|number
for multiple possible types!nil
or!table
to exclude a typeinteger
is a number with no fractional componentnumber[0,9]
is a number >= 0 and <= 9number(-5,9)
is a number > -5 and < 9
A __type or __class metamethod could make this a bit more effective.
function (x, y=2, z=y)
...
end
-- Turns into
function (x, y, z)
y = (y~=nil) or 2
z = (z~=nil) or y
...
end
This patch adds += -= *= /=
as well as <<= >>= &= |= ^=
.
http://lua-users.org/files/wiki_insecure/power_patches/5.4/plusequals-5.4.patch
I want to add __addassign, __subassign, __mulassign, __divassign, and possible same for bitwise ops. These would fall back on __add, etc.
table.merge({a=1, b=2}, {z=1, 10})
-- Gives
{10, a=1, b=2, z=1}
table.deepcopy({a=1, b=2, {c=3}})
-- Gives an identical copy of the table. Will not copy metatables. Unsure what
-- intended behavior is for reference loops.
turns t?.u?.v
into t and t.u and t.u.v
http://lua-users.org/files/wiki_insecure/power_patches/5.2/safe2.patch
This patch enables alternate syntax, good for ‘set’ types http://lua-users.org/files/wiki_insecure/power_patches/5.3/jh-lua-setinit-5.3.1.patch
{.cat, x=true}
turns into {cat = true, x = true}
among other things. I do
think it may be more useful to set things to 1,2,3 etc. instead of ‘true’
because it would allow for a sort of enum type.
Allows obj = {function x () end}
to mean obj = {x = function (self) end}
http://lua-users.org/files/wiki_insecure/power_patches/5.2/oofunc.diff
<a> xor <b> -- Assume <a> and <b> are expressions
-- Turns into
local a,b = <a>,<b>
(a and (not b) and a) or ((not a) and b)
Binary numbers: http://lua-users.org/files/wiki_insecure/power_patches/5.2/jh-lua-bin-5.2.1.patch
Octal numbers may be wanted. Also, being able to put underscores in number literals would make large numbers easier to read.
Returns a number representing an object’s value. This would help with handling of numerical-representative types such as fractions.