In this example on Wikipedia (http://en.wikipedia.org/wiki/Closure_(computer_programming) ) it claims that invoking the variable closure1 with closure1(3) will return 4. Can someone walk through the example - I don't understand.
function startAt(x)
function incrementBy(y)
return x + y
return incrementBy
variable closure1 = startAt(1)
variable closure2 = startAt(5)
Invoking the variable closure1 (which is of function type) with closure1(3) will return 4, while invoking closure2(3) will return 8. While closure1 and closure2 are both references to the function incrementBy, the associated environment will bind the identifier x to two distinct variables in the two invocations, leading to different results.
If it helps, here's my current understanding. variable closure1 = startAt(1) sets the variable closure1 to the function startAt() which by default is initialized to 1. However, invoking closure1(3) sets this default value to 3. What I don't understand then is where does y come from.
variable closure1 = startAt(1)
When you run startAt, you're creating a new function. Every time you run startAt, you're creating a brand new function. Therefore, we understand that the code
variable closure1 = startAt(1)
variable closure2 = startAt(5)
creates two distinct functions and stores them in colsure1 and closure2. The function startAt is like a factory that returns new functions. You've called it twice, and created two functions. Those two created functions are stored inside closure1 and closure2.
Here's what "closure" means: each function caries around its own variable environment. A variable environment is the set of external variables the function can see. A function builds its variable environment when it is created, based on all of the variables currently in scope. (The technical definition of a closure is: "functional code plus variable environment".)
When a call to startAt creates a new function, that new function builds its variable environment. The new function's variable environment includes the variable x that exists in-scope within the particular call to startAt.
So, the first call to startAt(1) has a variable x that equals 1. The function that is created inside that call to startAt has a variable environment includes that x equal to 1.
Functions can have arguments. The functions created by startAt each expect a single argument called y. Therefore, when you perform x + y when calling the created function, the y is supplied as an argument by that particular call, and the x is supplied by that function's variable environment. When you call closure1(3), the value of the argument y is 3 and the value of x (from the function's variable environment) is 1, so you get the result 4.
The second call to startAt creates a totally new variable x. This x has a value of 5. The function created by this second call to startAt has a different variable environment, which includse this new x whose value is 5. When you call that newly created function with closure2(3), we have x=5 and y=3, so x+y gives the result 8.
Related
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.
According to Lua's manual
Global variables do not need declarations. You simply assign a value to a global variable to create it. It is not an error to access a non-initialized variable; you just get the special value nil as the result
I think declaration is good, it makes thing more manageable. Why did Lua skip declarations for Global variables? I guess they have a good reason but I don't know why.
What if I make this mistake
-- Activation Code
function TestLoco:OnActivate()
self.MyGlobal = "ABC"; --Init the global variable
end
-- Run every tick
function TestLoco:OnTick()
self.MyGIobaI = "BCD"; --Edit the global variable at every tick, but I mistake 'I' with 'l'
end
-- Call when I click the mouse
function TestLoco:OnClick()
Debug.Log(self.MyGlobal); --This print "ABC", but It should be "BCD", what if I don't notice this?
end
Because Lua has no classes. self.MyGlobal is not a global variable, it is a field in the table passed via the self parameter. The syntax is equivalent to self["MyGlobal"]. For a "true" global variable assignment (e.g. x = 0), it is equivalent to _G["x"] = 0, where _G is the global environment table.
Since Lua has no notion of classes, the type of self is simply a table. The syntax you use for specifying a "method" is just a syntactic shortcut to this:
TestLoco.OnActivate = function(self)
self["MyGlobal"] = "ABC";
end
It's just a function that assigns a field in a table. It could be called with potentially any table, hence it cannot verify the table actually should have that field.
However, Lua offers some pretty good run-time customisable checking via metatables. If you build a table specifying the "class" of a table, you can assign a metatable to every table that checks the assignment each time if it assigns to a field that you actually "declared".
I know this is very basic question but i'm pretty much confused by the local variables & their scope in lua, for instance if i write local x=12, it means that the variable x is a local variable & it's value is 12, but instead if i write local x & in the next line x=12, does this mean the same as in previous case or x=12 is treated as a global variable?
You can think of it as two totally independent things:
local x creates a "slot" in the local scope to hold a value, i.e. a variable. This variable is named x. From that point forward, until you exit that scope, any reference to x will refer to that local x.
x = 12 puts a value into the variable x. If you've previously created a local slot named x, that's where it'll go. If there is no local x in scope, it'll go into the global scope.
local x = 12 is just a shorthand for combining these two things, creating a local variable and assigning it a value at the same time.
So yes, your two scenarios are effectively equivalent.
local x
x = 12
And
local x = 12
Do the same thing.
You only use the local keyword once per scope, so that second access of x in your example will use the local x. If you then wish to access the global x, you can use __G.x
I want to know how to return a value after my function finishes running.
I have, for example:
FUNCTION X
? X ⍴ 10
//This means, generate X random numbers (X is the function's argument) within the range 1-10.
I just want to know how I can return the value of the function, and for example, pass it to another function.
Thank you for your help!
This is done in the Function header (code line 0).
It has the following form:
returnValue ← leftArgument functionName rightArgument ; localized_variables
So, whenever your function terminates, the value of the variable returnValue will be returned.
Alternately, if your APL system supports it, you can use direct definition (dfns, lambdas). This should work in Dyalog, GNU, NARS2000, and NGN APL.
Try
{?⍵⍴10} 42
⍵ is the function's argument (X in your example)
The return value is the result of the expression and does not have to be explicitly stated.
You can also do
function←{?⍵⍴10}
then
function 42
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