How Do Lexical Closures Work

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:

  1. A function and
  2. 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



Leave a reply



Submit