Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a closure? Does java have closures? [duplicate]

I was reading Object Oriented Javascript and found the concept of closures. I didn't quite understand why and when it is used. Do other languages like Java also have closures? I basically want to understand how knowing the concept of closures can help me improve my coding.

like image 220
sushil bharwani Avatar asked Sep 27 '10 15:09

sushil bharwani


People also ask

What is a Java closure?

A closure is a function (or method) that refers to free variables in their lexical context. The function is a block of code with parameters. It may produce a result value (return type). A free variable is an identifier used but not defined by the closure. It can be used without being a method or a class.

What is closures and disadvantages of closures?

Disadvantages of closures There are two main disadvantages of overusing closures: The variables declared inside a closure are not garbage collected. Too many closures can slow down your application. This is actually caused by duplication of code in the memory.

What is closure Mcq?

Solution(By Examveda Team) A combination of a function object and a scope (a set of variable bindings) in which the function's variables are resolved is called a closure.

Is closure available in Java?

Java does not have closures.


4 Answers

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);
    }
}
like image 176
mikera Avatar answered Sep 28 '22 11:09

mikera


Closures are know by various names in various languages but the essential points are as follows:

To create closures you need a language where the function type is a 1st class citizen i.e. it can be bound to a variable and passed around like any old string, int or bool.

You also need to be able to declare functions inline. In javascript you can do something like this:

foo("bar", "baz" function(x){alert("x")});

To pass a anonymous function as a parameter to the foo function. We can use this to create a closure.

Closures "close over" variables so can be used to pass scoped variables around. Consider this example:

function foo(){
    var spam = " and eggs";
    return function(food){alert(food + spam)};
}
var sideOfEggs = foo();

The side of eggs now contains a function which appends " and eggs" to whatever foodstuff it is passed. The spam variable is part of the foo function scope and would have been lost when the function exited, except that the closure "closed over" the namespace preserving it as long as the closure remains in memory.

So we're clear on closures having access to their parent's private scoped variables right? So how about using them to simulate private access modifiers in javascript?

var module = (function() {   
    var constant = "I can not be changed";

     return {
         getConstant    :    function() {  //This is the closure
            return constant;               //We're exposing an otherwise hidden variable here
         }
    };
}());                                     //note the function is being defined then called straight away

module.getConstant();                     //returns "I can not be changed"
module.constant = "I change you!";
module.getConstant();                     //still returns "I can not be changed" 

So what's happening here is we're creating and immediately calling an anonymous function. There is one private variable in the function. It returns an object with a single method which references this variable. Once the function has exited the getConstant method is the sole way of accessing the variable. Even if this method is removed or replaced it will not give up it's secret. We have used closures to achieve encapsulation and variable hiding. For a more thorough explanation of this see http://javascript.crockford.com/private.html

Java does not have closures (yet). The closest it has are anonymous inner classes. However to instantiate one of these inline you have to instantiate an entire object (usually from an existing interface).The beauty of closures is they encapsulate simple, expressive statements which is somewhat lost in the noise of anonymous inner classes.

like image 41
Ollie Edwards Avatar answered Sep 28 '22 11:09

Ollie Edwards


While Java doesn't have first-class functions, it does in fact have lexical closures.

For instance, the following Lisp function (stolen from Paul Graham's book On Lisp) returns a function that adds a number:

(defun make-adder (n)
  (lambda (x) (+ x n))

This can be done in Java. However, since it doesn't have first-class functions, we need to define an interface (let's call it Adder) and an anonymous inner class with a function that implements this interface.

public interface Adder {
    int add(int x);
}

public static Adder makeAdder(final int n) {
    return new Adder() {
        public int add(int x) {
            return x + n;
        }
    };
}

The inner add() function is a lexical closure because it uses the n variable from the outer lexical scope.

The variable had to be declared final in order to do this, which means that the variable cannot change. However, changing values within reference variables is possible, even if they are final. For instance, consider the following Lisp function (also from On Lisp):

(defun make-adderb (n)
  (lambda (x &optional change)
    (if change
        (setq n x)
        (+ n n))))

This can be implemented in Java by wrapping the outer variable in a reference type variable, such as an array or object.

public interface MutableAdder {
    int add(int x, boolean change);
}

public static MutableAdder makeAdderB(int n) {
    final int[] intHolder = new int[] { n };
    return new MutableAdder() {
        public int add(int x, boolean change) {
            if (change) {
                intHolder[0] = x;
                return x;
            }
            else {
                return intHolder[0] + x;
            }
        }
    };
}

I will claim that this is real lexical closures, not a simulation. But I won't claim that it's pretty.

like image 32
Soulman Avatar answered Sep 28 '22 12:09

Soulman


A closure is a scoping technique. Java does not have closures.

In javascript you can do something like that following:

var scope = this;

var f = function() {
    scope.somethingOnScope //scope is 'closed in' 
}

if you then do something like pass f to a function, scope is the scope of where it was defined.

like image 34
hvgotcodes Avatar answered Sep 28 '22 10:09

hvgotcodes