Skip to content

Instantly share code, notes, and snippets.

@wrongbyte
Last active September 30, 2022 01:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wrongbyte/3b5f0b09706d818e24c5b18c4b2639cb to your computer and use it in GitHub Desktop.
Save wrongbyte/3b5f0b09706d818e24c5b18c4b2639cb to your computer and use it in GitHub Desktop.
closures and nested functions

Nested functions, closures and first-class functions

Closures store the environment along with a function. However, closures are only meaningful when a function can be excecuted from outside the scope in which it's declared.

In languages without first-class functions, you could still have nested functions, but they couldn't be used as closures, because you would not be able to execute a function outside of its original scope (since you could not assign this function to any other variable, pass it as an argument or return this function by another function).

Let's see it clearer with some examples:

function outer1() {
  const foo = 42;

  function inner1() {};
}

inner1 is not a closure, but a nested function. It takes no variables from the surrounding scope.

function outer2() {
  const foo = 42;

  function inner2() { return foo; };

  return inner2();
}

In this example, inner2 uses foo (a variable from the surrounding scope), but never leaves the scope of outer2. It is simply returning a variable of the outer scope, and being returned by the outer function. We don't use inner2 outside of outer2.

function outer3() {
  const foo = 42;

  function inner3() { return 23; };

  return inner3;
}

Here, inner3 leaves the scope of outer3, but without using any free variable - therefore, it is not a closure.

function outer4() {
  const foo = 42;

  function inner4() { return foo; };

  return inner4;
}

Here, inner4 uses a free variable - foo - and also leaves the scope of outer4. We can then assign outer4 to a variable, for example, and call it to get inner4. Normally when a function exits, all its local variables are blown away. However, if we return the inner function and assign it to a variable fnc so that it persists after outer has exited, all of the variables that were in scope when inner was defined also persist. Note that it is only possible because we can return a function from another function - which means having first-class functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment