lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


A couple of years ago I proposed a syntax like: function [a, b,
c]foo(x, y, z) end

The point of that proposal was to introduce an explicit specification
of "captured" variables that were external to the function, i.e.,
upvalues and globals, the a, b and c in [a, b, c]. Already then I
mentioned that the keyword function is redundant in that syntax, so
[a, b, c]foo(x, y, z) end may already be sufficient to define a
function. The syntax had been inspired by the lambda syntax of C++, so
the similarity is not coincidental. An anonymous function without
captures would look like [](x, y, z) end, an anonymous function that
captures everything: [*](x, y, z) end.

Despite the C++ heritage of the proposal, one trait of the C++ syntax
was not borrowed, and I think that was wrong. In C++, a lambda can
have two kinds of captures: "by reference" and "by value". "By
reference" is somewhat similar in spirit to Lua upvalues, while "by
value" is not. The latter creates, in Lua terms, an upvalue that is
not linked to the original variable, but is initialized with the value
of the original variable. This is useful, but, I believe, cannot be
expressed tersely in Lua. To capture variable x by value, one would
have do something like:

do
    local z = x
    local function foo(...) ... use z ... end
end

Another useful trait of C++ captures is that one could rename the
captured variable like in [foo=bar].

So I propose further extension for the syntax of captures:

[a] -- a is captured "by reference" (regular upvalue)
[+a] -- a is captured "by value" (upvalue of a copy)
[a=b] -- b is captured by reference and is renamed as a
[+a=b] -- b is captured by value and is renamed as a
[*] -- capture everything by reference (or: [&] as in C++)
[+]  -- capture everything by value
[x, y, z, ...] -- each of x, y, z, ... can be any of the above

Cheers,
V.