Advertisement
Advertisement


Does Java need closures?


Question

I've been reading a lot lately about the next release of Java possibly supporting closures. I feel like I have a pretty firm grasp on what closures are, but I can't think of a solid example of how they would make an Object-Oriented language "better". Can anyone give me a specific use-case where a closure would be needed (or even preferred)?

2015/04/28
1
45
4/28/2015 7:43:16 PM


They don't make an Object-Oriented language better. They make practical languages more practical.

If you're attacking a problem with the OO hammer - represent everything as interactions between objects - then a closure makes no sense. In a class-based OO language, closures are the smoke-filled back rooms where stuff gets done but no one talks about it afterwards. Conceptually, it is abhorrent.

In practice, it's extremely convenient. I don't really want to define a new type of object to hold context, establish the "do stuff" method for it, instantiate it, and populate the context... i just want to tell the compiler, "look, see what i have access to right now? That's the context i want, and here's the code i want to use it for - hold on to this for me 'till i need it".

Fantastic stuff.

2008/09/08

The most obvious thing would be a pseudo-replacement for all those classes that just have a single method called run() or actionPerformed() or something like that. So instead of creating a Thread with a Runnable embedded, you'd use a closure instead. Not more powerful than what we've got now, but much more convenient and concise.

So do we need closures? No. Would they be nice to have? Sure, as long as they don't feel bolted on, as I fear they would be.

2008/09/08

I suppose for supporting core functional programming concepts, you need closures. Makes the code more elegant and composable with the support for closures. Also, I like the idea of passing around lines of code as parameters to functions.

2008/09/08

There are some very useful 'higher order functions' which can do operations on lists using closures. Higher order functions are functions having 'function objects' as parameters.

E.g. it is a very common operation to apply some transformation to every element in a list. This higher order function is commonly called 'map' or 'collect'. (See the *. spread operator of Groovy).

For example to square each element in a list without closures you would probably write:

List<Integer> squareInts(List<Integer> is){
   List<Integer> result = new ArrayList<Integer>(is.size());
   for (Integer i:is)
      result.add(i*i);
   return result;
}

Using closures and map and the proposed syntax, you could write it like that:

is.map({Integer i => i*i})

(There is a possible performance problem here regarding boxing of primitive types.)

As explained by Pop Catalin there is another higher order function called 'select' or 'filter': It can be used to get all the elements in a list complying to some condition. For example:

Instead of:

void onlyStringsWithMoreThan4Chars(List<String> strings){
   List<String> result = new ArrayList<String>(str.size()); // should be enough
   for (String str:strings)
      if (str.length() > 4) result.add(str);
   return result;
}

Instead you could write something like

strings.select({String str => str.length() > 4});

using the proposal.

You might look at the Groovy syntax, which is an extension of the Java language to support closures right now. See the chapter on collections of the Groovy User Guide for more examples what to do with closures.

A remark:

There is perhaps some clarification needed regarding the term 'closure'. What I've shown above are strictly spoken no closures. They are just 'function objects'. A closure is everything which can capture - or 'close over' - the (lexical) context of the code surrounding it. In that sense there are closures in Java right now, i.e. anonymous classes:

Runnable createStringPrintingRunnable(final String str){
    return new Runnable(){
       public void run(){
          System.out.println(str); // this accesses a variable from an outer scope
       }
    };
}
2008/09/15

Java doesn't need closures, an Object oriented language can do everything a closure does using intermediate objects to store state or do actions (in Java's case inner classes). But closures are desirable as a feature because they greatly simplify the code and increase readability and as a consequence the maintainability of the code.

I'm no Java specialist but I'm using C# 3.5 and closures are one of my favorite features of the language, for example take the following statement as an example:

// Example #1 with closures
public IList<Customer> GetFilteredCustomerList(string filter) {
    //Here a closure is created around the filter parameter
    return Customers.Where( c => c.Name.Contains(filter)).ToList();
}

now take an equivalent example that doesn't use closures

//Example #2 without closures, using just basic OO techniques
public IList<Customer> GetFilteredCustomerList(string filter) {
    return new Customers.Where( new CustomerNameFiltrator(filter));
}
... 
public class CustomerNameFiltrator : IFilter<Customer> {
    private string _filter;
    public  CustomerNameFiltrator(string filter) {
         _filter = filter;
    }
    public bool Filter(Customer customer) {
        return customer.Name.Contains( _filter);
    }
}

I know this is C# and not Java but the idea is the same, closures are useful for conciseness, and make code shorter and more readable. Behind the scenes, the closures of C# 3.5 do something that's looks very similar to example #2 meaning the compiler creates a private class behind the scenes and passes the 'filter' parameter to it.

Java doesn't need closures to work, as a developer you don't need them either, but, they are useful and provide benefits so that means that they are desirable in a language that is a production language and one of it's goals is productivity.

2008/09/10

Source: https://stackoverflow.com/questions/50255
Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Email: [email protected]