Parenless calls for function literals

139 views
Skip to first unread message

TopchetoEU

unread,
May 28, 2026, 2:11:22 PMMay 28
to lu...@googlegroups.com
Hello list,

Lua allows calls with table and string literals to omit the call parens, which enables some very elegant and concise DSL-styled syntax. I have been experimenting with extending that idea to function literals, too. This is the core of the syntax:

called_function begin
body_of_function_literal
end

I chose to introduce `begin` as a keyword, as opposed to using the existing `function` keyword, as syntax like this:

print("Hello, world")
function test() end

Would be difficult to parse (not impossible, but would require a look ahead, which would complicate needlessly the parser for such a small feature).

I'm not terribly attached to the `begin` keyword, and I even fear that it could break existing code, as `begin` could be a common variable/field name, so I'm open to suggestions.

Otherwise, I think this would make DSLs much cleaner in some cases, where you need to pass functions, instead of tables. For example, a testing framework could declare its cases like this:

describe "My example test" begin
it "Should be true" begin
assert.truthy(true)
end
end

I have attached a patch file, so you can experiment with it. Note that I haven't spent much time testing it, but nothing *should* break, as it changes about 15 LoC.

Comments and criticism are welcome.
lua-begin.patch

Luiz Henrique de Figueiredo

unread,
May 28, 2026, 2:20:49 PMMay 28
to lu...@googlegroups.com
> called_function begin
> body_of_function_literal
> end

Transforming '<name> begin' to 'function <name>()' is very easy with
ltokenp, my token processor:
https://web.tecgraf.puc-rio.br/~lhf/ftp/lua/#ltokenp

The advantage of ltokenp is that you can experiment with syntax
without patching the Lua source code.
--lhf

Sainan

unread,
May 28, 2026, 2:30:33 PMMay 28
to lu...@googlegroups.com
My 2 cents:

-- Test library
local units = {}
local unit_currently_describing
__atexit = setmetatable({}, {
__gc = function()
for unit_name, unit in pairs(units) do
for test_name, test in pairs(unit) do
local ok, msg = pcall(test)
if not ok then
print("Test failure in " .. unit_name .. "'s test \"" .. test_name .. "\": " .. msg)
end
end
end
end
})
function describe(name)
units[name] = {}
unit_currently_describing = name
end
function it(name, func)
units[unit_currently_describing][name] = func
end

-- Test code
describe "Foo" do
it("1 is true", function()
assert(1)
end)
end
describe "Bar" do
it("0 is true", function()
assert(0)
end)
end

-- Sainan

TopchetoEU

unread,
May 29, 2026, 7:47:19 AMMay 29
to lu...@googlegroups.com
Your tool wouldn't nicely transform this syntax, as I'm trying to transform `expression begin stm1 stm2 stm3 end` to `expression(function(...) stm1 stm2 stm3 end)`, which on the token level is exponentially harder, because you need to know where the function body ends, so that you can insert the closing call parenthesis.

Off the top of my head, I can think of a scheme where you count then-end, do-end and repeat-until pairs, so you know which `end` token matches `begin`. That however would be more cumbersome than just patching the lua code itself.

TopchetoEU

unread,
May 29, 2026, 8:00:11 AMMay 29
to lu...@googlegroups.com
IMHO, doing it like this is quite cumbersome, as you need to keep track of global state, which gets messier the bigger the code gets. With my syntax, you get all the benefits of passing a callback to the callee.

Martin Eden

unread,
May 30, 2026, 12:19:34 PM (13 days ago) May 30
to lu...@googlegroups.com
On 2026-05-29 13:47, 'TopchetoEU' via lua-l wrote:
> Your tool wouldn't nicely transform this syntax, as I'm trying to transform `expression begin stm1 stm2 stm3 end` to `expression(function(...) stm1 stm2 stm3 end)`, which on the token level is exponentially harder, because you need to know where the function body ends, so that you can insert the closing call parenthesis.
Yeah ltokenp is tool for transpiling Lua code to something else. Not
vice versa.

-- Martin

Reply all
Reply to author
Forward
0 new messages