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)?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
Java has had closures since 1.1, just in a very cumbersome and limited way.
They are often useful wherever you have a callback of some description. A common case is to abstract away control flow, leaving the interesting code to call an algoritm with a closure that has no external control flow.
A trivial example is for-each (although Java 1.5 already has that). Whilst you can implement a forEach method in Java as it stands, it's far too verbose to be useful.
An example which already makes sense with existing Java is implementing the "execute around" idiom, whereby resource acquisition and release is abstracted. For instance, file open and close can be done within try/finally, without the client code having to get the details right.
As a java developer who is trying to teach themselves lisp in an attempt to become a better programmer, I would say that I would like to see the Josh Block proposal for closures implemented. I find myself using anonymous inner classes to express things like what to do with each element of a list when aggregating some data. To would be nice to represent that as a closure, instead of having to create an abstract class.
Not only that benjismith, but I love how you can just do...
myArray.sort{ it.myProperty }
You only need the more detailed comparator you've shown when the natural language comparison of the property doesn't suit your needs.
I absolutely love this feature.
Now that JDK8 is about to be released there is more information available that can enrich the answers to this question.
Bria Goetz, language architect at Oracle, has published a series of papers (yet drafts) on the current state of lambda expressions in Java. It does also cover closures as they are planning to release them in the upcoming JDK, which should be code complete around January 2013 and should be released around midyear 2013.
As a Lisp programmer I would wish that the Java community understands the following difference: functions as objects vs. closures.
a) functions can be named or anonymous. But they can also be objects of themselves. This allows functions to be passed around as arguments, returned from functions or stored in data structures. This means that functions are first class objects in a programming language.
Anonymous functions don't add much to the language, they just allow you to write functions in a shorter way.
b) A closure is a function plus a binding environment. Closures can be passed downwards (as parameters) or returned upwards (as return values). This allows the function to refer to variables of its environment, even if the surrounding code is no longer active.
If you have a) in some language, then the question comes up what to do about b)? There are languages that have a), but not b). In the functional programming world a) (functions) and b (functions as closures) is nowadays the norm. Smalltalk had a) (blocks are anonymous functions) for a long time, but then some dialects of Smalltalk added support for b) (blocks as closures).
You can imagine that you get a slightly different programming model, if you add functions and closures to the language.
From a pragmatic view, the anonymous function adds some short notation, where you pass or invoke functions. That can be a good thing.
The closure (function plus binding) allows you for example to create a function that has access to some variables (for example to a counter value). Now you can store that function in an object, access it and invoke it. The context for the function object is now not only the objects it has access to, but also the variables it has access to via bindings. This is also useful, but you can see that variable bindings vs. access to object variables now is an issue: when should be something a lexical variable (that can be accessed in a closure) and when should it be a variable of some object (a slot). When should something be a closure or an object? You can use both in the similar ways. A usual programming exercise for students learning Scheme (a Lisp dialect) is to write a simple object system using closures.
The result is a more complicated programming language and a more complicated runtime model. Too complicated?
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.