Asked  7 Months ago    Answers:  2   Viewed   23 times

I asked a question about Currying and closures were mentioned. What is a closure? How does it relate to currying?

 Answers

12

Variable scope

When you declare a local variable, that variable has a scope. Generally, local variables exist only within the block or function in which you declare them.

function() {
  var a = 1;
  console.log(a); // works
}    
console.log(a); // fails

If I try to access a local variable, most languages will look for it in the current scope, then up through the parent scopes until they reach the root scope.

var a = 1;
function() {
  console.log(a); // works
}    
console.log(a); // works

When a block or function is done with, its local variables are no longer needed and are usually blown out of memory.

This is how we normally expect things to work.

A closure is a persistent local variable scope

A closure is a persistent scope which holds on to local variables even after the code execution has moved out of that block. Languages which support closure (such as JavaScript, Swift, and Ruby) will allow you to keep a reference to a scope (including its parent scopes), even after the block in which those variables were declared has finished executing, provided you keep a reference to that block or function somewhere.

The scope object and all its local variables are tied to the function and will persist as long as that function persists.

This gives us function portability. We can expect any variables that were in scope when the function was first defined to still be in scope when we later call the function, even if we call the function in a completely different context.

For example

Here's a really simple example in JavaScript that illustrates the point:

outer = function() {
  var a = 1;
  var inner = function() {
    console.log(a);
  }
  return inner; // this returns a function
}

var fnc = outer(); // execute outer to get inner 
fnc();

Here I have defined a function within a function. The inner function gains access to all the outer function's local variables, including a. The variable a is in scope for the inner function.

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. The variable a has been closed over -- it is within a closure.

Note that the variable a is totally private to fnc. This is a way of creating private variables in a functional programming language such as JavaScript.

As you might be able to guess, when I call fnc() it prints the value of a, which is "1".

In a language without closure, the variable a would have been garbage collected and thrown away when the function outer exited. Calling fnc would have thrown an error because a no longer exists.

In JavaScript, the variable a persists because the variable scope is created when the function is first declared and persists for as long as the function continues to exist.

a belongs to the scope of outer. The scope of inner has a parent pointer to the scope of outer. fnc is a variable which points to inner. a persists as long as fnc persists. a is within the closure.

Tuesday, June 1, 2021
 
CBroe
answered 7 Months ago
33

A closure is a first class function with bound variables.

Roughly that means that:

  • You can pass the closure as a parameter to other functions
  • The closure stores the value of some variables from the lexical scope that existed at the time that is was created

Java initially didn't have syntactic support for closures (these were introduced in Java 8), although it was fairly common practice to simulate them using anonymous inner classes. Here's an example:

import java.util.Arrays;
import java.util.Comparator;

public class StupidComparator { 
    public static void main(String[] args) {
        // this is a value used (bound) by the inner class
        // note that it needs to be "final"
        final int numberToCompareTo=10;

        // this is an inner class that acts like a closure and uses one bound value
        Comparator<Integer> comp=new Comparator<Integer>() {
            public int compare(Integer a, Integer b) {
                int result=0;
                if (a<numberToCompareTo) result=result-1;
                if (b<numberToCompareTo) result=result+1;
                return result;
            }
        };

        Integer[] array=new Integer[] {1,10, 5 , 15, 6 , 20, 21, 3, 7};

        // this is a function call that takes the inner class "closure" as a parameter
        Arrays.sort(array,comp);

        for (int i:array) System.out.println(i);
    }
}
Sunday, August 1, 2021
 
EastSw
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share