How do lexical closures work?
Python is actually behaving as defined. Three separate functions are created, but they each have the closure of the environment they're defined in - in this case, the global environment (or the outer function's environment if the loop is placed inside another function). This is exactly the problem, though - in this environment, i is modified, and the closures all refer to the same i.
Here is the best solution I can come up with - create a function creater and invoke that instead. This will force different environments for each of the functions created, with a different i in each one.
flist = []
for i in xrange(3):
def funcC(j):
def func(x): return x * j
return func
flist.append(funcC(i))
for f in flist:
print f(2)
This is what happens when you mix side effects and functional programming.
How do JavaScript closures work?
A closure is a pairing of:
- A function and
- A reference to that function's outer scope (lexical environment)
A lexical environment is part of every execution context (stack frame) and is a map between identifiers (i.e. local variable names) and values.
Every function in JavaScript maintains a reference to its outer lexical environment. This reference is used to configure the execution context created when a function is invoked. This reference enables code inside the function to "see" variables declared outside the function, regardless of when and where the function is called.
If a function was called by a function, which in turn was called by another function, then a chain of references to outer lexical environments is created. This chain is called the scope chain.
In the following code, inner
forms a closure with the lexical environment of the execution context created when foo
is invoked, closing over variable secret
:
function foo() {
const secret = Math.trunc(Math.random() * 100)
return function inner() {
console.log(`The secret number is ${secret}.`)
}
}
const f = foo() // `secret` is not directly accessible from outside `foo`
f() // The only way to retrieve `secret`, is to invoke `f`
How exactly does a Closure remember its lexical scope?
Is a reference to the original variable getting returned with the function....or some copy that's hidden? What's actually going on?
Essentially, yes. The returned function carries along with it its enclosing scope, which includes the variables in that scope. It's not a copy of those variables--it's the scope itself. That is the essence of closures.
What is lexical scope?
I understand them through examples. :)
First, lexical scope (also called static scope), in C-like syntax:
void fun()
{
int x = 5;
void fun2()
{
printf("%d", x);
}
}
Every inner level can access its outer levels.
There is another way, called dynamic scope used by the first implementation of Lisp, again in a C-like syntax:
void fun()
{
printf("%d", x);
}
void dummy1()
{
int x = 5;
fun();
}
void dummy2()
{
int x = 10;
fun();
}
Here fun
can either access x
in dummy1
or dummy2
, or any x
in any function that call fun
with x
declared in it.
dummy1();
will print 5,
dummy2();
will print 10.
The first one is called static because it can be deduced at compile-time, and the second is called dynamic because the outer scope is dynamic and depends on the chain call of the functions.
I find static scoping easier for the eye. Most languages went this way eventually, even Lisp (can do both, right?). Dynamic scoping is like passing references of all variables to the called function.
As an example of why the compiler can not deduce the outer dynamic scope of a function, consider our last example. If we write something like this:
if(/* some condition */)
dummy1();
else
dummy2();
The call chain depends on a run time condition. If it is true, then the call chain looks like:
dummy1 --> fun()
If the condition is false:
dummy2 --> fun()
The outer scope of fun
in both cases is the caller plus the caller of the caller and so on.
Just to mention that the C language does not allow nested functions nor dynamic scoping.
Closures and lexical environment in javascript
Clouser is made when function is created, cause only then you have local variables in your scope that are going into closer.
When function is executed that's the closure in action, you are accessing the variables that went into closure. See the example from the very top on this page.
Lexical scope/closures in javaScript
You, my friend, are thoroughly confused. Your very first statement itself is wrong:
functions create their environment (scope) when they are defined not when they are executed
Actually it's the opposite. Defining a function doesn't create a scope. Calling a function creates a scope.
What's a scope?
To put it simply, a scope is the lifespan of a variable. You see, every variable is born, lives and dies. The beginning of a scope marks the time the variable is born and the end of the scope marks the time it dies.
In the beginning there's only one scope (called the program scope or the global scope). Variables created in this scope only die when the program ends. They are called global variables.
For example, consider this program:
const x = 10; // global variable x
{ // beginning of a scope
const x = 20; // local variable x
console.log(x); // 20
} // end of the scope
console.log(x); // 10
Lexical Scope/Closures and Global Function Recursion
Basically right, a few points:
Each call to fnTest creates a unique object in which the variables currentIdx and endIdx are stored for the lifetime of that call...
For the lifetime of that object, which as Felix said is called an environment. That lifetime is like the lifetime of all other objects: As long as something still has a reference to it. In particular, it continues (in this case) after fnTest
has returned.
The only things that can have references to these environment objects are the functions created within them, which are called closures (they "close over" the environment).
...and all sub-routines within that call (this is called a closure)
The functions are called closures, not the environment.
The setTimeout call creates a new object from the anonymous function
No, your code is creating an anonymous function and passing a reference to that function into setTimeout
.
...which has access to the fnTest closure and can therefore reference currentIdx and endIdx
it has access to the environment where it was created
this object/function will execute after a 100ms delay. Upon execution the anonymous function will itself create a new fnTest closure by calling fnTest.
It creates a new environment by calling fnTest
, yes.
At this point the original fnTest closure referenced by the anonymous function may be disposed of.
Since the timer mechanism has released its reference to the anonymous function, nothing references the anonymous function anymore, and it can be garbage-collected. Since it's the only thing referencing the environment from the initial call to fnTest
, that environment can also be garbage-collected.
We're doing a little bit of hand-waving around details in the above, but the important concepts are present and correct.
Related Topics
How to Improve Performance of This Code
How to Do Fuzzy Match Merge With Python Pandas
Python: Justifying Numpy Array
Is There a Standardized Method to Swap Two Variables in Python
Pandas Groupby With Delimiter Join
Typeerror: Method() Takes 1 Positional Argument But 2 Were Given
What Is Getattr() Exactly and How to Use It
Finding and Replacing Elements in a List
Best Way to Return Multiple Values from a Function
How to Merge Lists into a List of Tuples
Meaning of @Classmethod and @Staticmethod For Beginner
How to Send a "Multipart/Form-Data" With Requests in Python