What does closure function mean for Lua? - lua

As per the guide(https://www.tutorialspoint.com/lua/lua_quick_guide.htm),
which says that:
array = {"Lua", "Tutorial"}
function elementIterator (collection)
local index = 0
local count = #collection
-- The closure function is returned
return function ()
index = index + 1
if index <= count
then
-- return the current element of the iterator
return collection[index]
end
end
end
for element in elementIterator(array)
do
print(element)
end
What does closure function mean for Lua?

In Lua, any function is a closure. In a narrower sense, a closure is an anonymous function like the returned function in your example.
Closures are first-class: they can be assigned to variables, passed to functions and returned from them. They can be both keys and values in Lua tables.
Unlike PHP or C++, closures have access to all variables in local scope鈥攗pvalues (in your example, index and count, which keep the iterator state, and also collection) with no need to declare upvalues explicitly. Upvalues survive when code execution leaves the block where they were set.
You cannot write an iterator without a closure (or a subroutine). In your example (a simple iterator), elementIterator is a function that receives a table and returns another function, a closure. This returned closure is called again and again by the generic for instruction until it returns nil.
You may find this paper interesting: https://www.lua.org/doc/jucs17.pdf.

Related

Why I can use a function to set a table index using arguments but i can't set a varble passed as a parameter

im new to lua (and programming 馃槄)
I would like to know why I can use a function to set a table index using arguments but i can't set a varble passed as a parameter like this :
variable = 1
function f(v)
v = 2
end
f(variable)
print(variable)
--prints 1
function f(t,i)
t[i] = 2
end
f(table,index)
print(table[1])
--prints 2
From the Lua manual:
Tables, functions, threads, and (full) userdata values are objects:
variables do not actually contain these values, only references to
them. Assignment, parameter passing, and function returns always
manipulate references to such values; these operations do not imply
any kind of copy
In your example variable is a number value which is none one of the mentioned types. Hence it is copied by value, not by reference.
So in
variable = 1
function f(v)
v = 2
end
f(variable)
v is a copy of variable, local to f. Changing v does not affect variable.
In
function f(t,i)
t[i] = 2
end
f(table,index)
print(table[1])
on the other hand, t is a reference to the same table, table refers to. Hence modifying t modifies the referred table.

How can a comma-separated return statement in Lua act as a function call?

I'm new to Lua and trying to figure out how the return statement in the squares function below is being used in the following code snippet:
function squares(iteratorMaxCount)
return square,iteratorMaxCount,0
end
The square parameter in the return statement refers to a function with the following signature:
function square(iteratorMaxCount,currentNumber)
What's confusing me is that the return statement looks like it's returning three values. What I think it's actually doing, however, is passing iteratorMaxCount and 0 as the arguments to a square function call.
Can anyone explain to me what's happening with this syntax? How is this serving as a function call as opposed to returning three values? In my mind, it feels as though the return statement should be written return square(iteratorMaxCount, 0) as opposed to return square, iteratorMaxCount, 0. I know that this is obviously wrong, but I can't figure out why.
I've tried searching through the Lua Manual, Lua Reference Guide, and searching Google, but I can't seem to find anything that explains this particular syntax. Can anyone point me in the right direction, please?
Thanks in advance.
Full code below via
Tutorialspoint
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
function squares(iteratorMaxCount)
return square,iteratorMaxCount,0
end
for i,n in squares(3)
do
print(i,n)
end
squares really does return three values, the first of which is a function. squares does not call square at all.
The trick here is how the for ... in syntax works. In the Lua 5.3 Reference Manual, section 3.3.5 says:
A for statement like:
for var_1, 路路路, var_n in explist do block end
is equivalent to the code:
do
local f, s, var = explist
while true do
local var_1, 路路路, var_n = f(s, var)
if var_1 == nil then break end
var = var_1
block
end
end
So the keyword "in" needs to be followed by three values:
an "iterator function" for getting the variables in each iteration
a "state" value to pass to the function each time
an initial value to pass to the function the first time
After the first time the function is called, the first value from the previous call is passed back into the next function call. When the first value returned from the function is nil, the for loop ends.
So in this example, squares(max) is designed to be used after "in", using square as the iterator function, max as the "state", 0 as the initial value, and a number and its square as the loop data values.

Trying to understand Custom Iterators

im trying to understand the iterators, in many examples I founf something like this:
function square(iteratorMaxCount,currentNumber)
if currentNumber<iteratorMaxCount
then
currentNumber = currentNumber+1
return currentNumber, currentNumber*currentNumber
end
end
function squares(iteratorMaxCount)
return square,iteratorMaxCount,0 // why not return square(iteratorMAxCount,0)????
end
for i,n in squares(3)
do
print(i,n)
end
First I dont understand the line I comment, and I dont find an easy example of how to do a Stateful Iterator and a Stateless iterator. Can anybody help me? thanks
From Lua Reference Manual 3.3.5:
A for statement like
for var_1, 路路路, var_n in explist do block end is equivalent to the code:
do
local f, s, var = explist
while true do
local var_1, 路路路, var_n = f(s, var)
if var_1 == nil then break end
var = var_1
block
end
end Note the following:
explist is evaluated only once. Its results are an iterator function,
a state, and an initial value for the first iterator variable. f, s,
and var are invisible variables. The names are here for explanatory
purposes only. You can use break to exit a for loop. The loop
variables var_i are local to the loop; you cannot use their values
after the for ends. If you need these values, then assign them to
other variables before breaking or exiting the loop.
So squares() has to return a function (square) a state (iteratorMaxCount) and an initial value (0) in order to work with a generic for loop.
Read the reference manual, Programming in Lua.

Dumping lua func with arguments

Is it possibly to dump the Lua table including function arguments?
If so, how can I do it?
I have managed to dump tables and function with addresses, but I haven't been able to figure out a way to get function args, i have tried different methods, but no luck.
So I want to receive them truth dumping tables and function plus args of the function.
Output should be something like this: Function JumpHigh(Player, height)
I don't know if it is even possible, but would be very handy.
Table only stores values.
If there's function stored in a table, then it's just a function body, there's no arguments. If arguments were applied, table would store only final result of that call.
Maybe you're talking about closure - function returned from other function, capturing some arguments from a top level function in a lexical closure? Then see debug.getupvalue() function to check closure's content.
Is this something what you're asking?
local function do_some_action(x,y)
return function()
print(x,y)
end
end
local t = {
func = do_some_action(123,478)
}
-- only function value printed
print "Table content:"
for k,v in pairs(t) do
print(k,v)
end
-- list function's upvalues, where captured arguments may be stored
print "Function's upvalues"
local i = 0
repeat
i = i + 1
local name, val = debug.getupvalue(t.func, i)
if name then
print(name, val)
end
until not name
Note that upvalues stored is not necessary an argument to a toplevel function. It might be some local variable, storing precomputed value for the inner function.
Also note that if script was precompiled into Lua bytecode with stripping debug info, then you won't get upvalues' names, those will be empty.

Some question about "Closure" in Lua

Here's my code, I confuse the local variable 'count' in the return function(c1,c2) with memory strack and where does they store in?
function make_counter()
local count = 0
return function()
count = count + 1
return count
end
end
c1 = make_counter()
c2 = make_counter()
print(c1())--print->1
print(c1())--print->2
print(c1())--print->3
print(c2())--print->1
print(c2())--print->2
in the return function(c1,c2) with memory strack and where does they store in?
It's stored in the closure!
c1 is not a closure, it is the function returned by make_counter(). The closure is not explicitly declared anywhere. It is the combination of the function returned by make_counter() and the "free variables" of that function. See closures # Wikipedia, specifically the implementation:
Closures are typically implemented with a special data structure that contains a pointer to the function code, plus a representation of the function's lexical environment (e.g., the set of available variables and their values) at the time when the closure was created.
I'm not quite sure what you're asking exactly, but I'll try to explain how closures work.
When you do this in Lua:
function() <some Lua code> end
You are creating a value. Values are things like the number 1, the string "string", and so forth.
Values are immutable. For example, the number 1 is always the number 1. It can never be the number two. You can add 1 to 2, but that will give you a new number 3. The same goes for strings. The string "string" is a string and will always be that particular string. You can use Lua functions to take away all 'g' characters in the string, but this will create a new string "strin".
Functions are values, just like the number 1 and the string "string". Values can be stored in variables. You can store the number 1 in multiple variables. You can store the string "string" in multiple variables. And the same goes for all other kinds of values, including functions.
Functions are values, and therefore they are immutable. However, functions can contain values; these values are not immutable. It's much like tables.
The {} syntax creates a Lua table, which is a value. This table is different from every other table, even other empty tables. However, you can put different stuff in tables. This doesn't change the unique value of the table, but it does change what is stored within that table. Each time you execute {}, you get a new, unique table. So if you have the following function:
function CreateTable()
return {}
end
The following will be true:
tableA = CreateTable()
tableB = CreateTable()
if(tableA == tableB) then
print("You will never see this")
else
print("Always printed")
end
Even though both tableA and tableB are empty tables (contain the same thing), they are different tables. They may contain the same stuff, but they are different values.
The same goes for functions. Functions in Lua are often called "closures", particularly if the function has contents. Functions are given contents based on how they use variables. If a function references a local variable that is in scope at the location where that function is created (remember: the syntax function() end creates a function every time you call it), then the function will contain a reference to that local variable.
But local variables go out of scope, while the value of the function may live on (in your case, you return it). Therefore, the function's object, the closure, must contain a reference to that local variable that will cause it to continue existing until the closure itself is discarded.
Where do the values get stored? It doesn't matter; only the closure can access them (though there is a way through the C Lua API, or through the Lua Debug API). So unlike tables, where you can get at anything you want, closures can truly hide data.
Lua Closures can also be used to implement prototype-based classes and objects. Closure classes and objects behave slightly differently than normal Lua classes and their method of invocation is somewhat different:
-- closure class definition
StarShip = {}
function StarShip.new(x,y,z)
self = {}
local dx, dy, dz
local curx, cury, curz
local engine_warpnew
cur_x = x; cur_y = y; cur_z = z
function setDest(x,y,z)
dx = x; dy=y; dz=z;
end
function setSpeed(warp)
engine_warpnew = warp
end
function self.warp(x,y,z,speed)
print("warping to ",x,y,x," at warp ",speed)
setDest(x,y,z)
setSpeed(speed)
end
function self.currlocation()
return {x=cur_x, y=cur_y, z=cur_z}
end
return self
end
enterprise = StarShip.new(1,3,9)
enterprise.warp(0,0,0,10)
loc = enterprise.currlocation()
print(loc.x, loc.y, loc.z)
Produces the following output:
warping to 0 0 0 at warp 10
1 3 9
Here we define a prototype object "StarShip" as an empty table.
Then we create a constructor for the StarShip in the "new" method. The first thing it does is create a closure table called self that contains the object's methods. All methods in the closure (those defined as 'function self.') are "closed" or defined for all values accessible by the constructor. This is why it's called a closure. When the constructor is done it returns the closure object "return self".
A lot more information on closure-based objects is available here:
http://lua-users.org/wiki/ObjectOrientationClosureApproach

Resources