Java Lambdas : How it works in JVM & is it OOP? [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
For example in the case of an anonymous inner class, an (anonymous) object reference is passed and methods of that object are executed.
Lambdas are code blocks which will be executed when needed.
What happens in the JVM when lambdas are encountered? Where does the JVM store the code blocks related to lambdas (Heap : Young, Old or Permanent Generation)?
I tried searching, and I got the syntax for using lambdas but was not able to understand what is happening inside JVM, as in JAVA everything is object-based.
So in context of OOP how do lambdas work?
Do lambdas violate OOP concepts?
Is Lambda good for the garbage collector as no objects are created hence
no worry about memory issues and clearing memory?

I wouldn't waste my time thinking whether the lambda expressions are a violation of OO principles. Its goal is to increase the power of a language and not to write an OO code, I don't see how lambdas can violate encapsulation, inheritance or polymorphism.
This article explains how Java handles lambda expressions:
What’s interesting about Lambda expressions is that from the JVM’s perspective they’re completely invisible. It has no notion of what an anonymous function or a Lambda expression is. It only knows bytecode which is a strict OO specification. It’s up to the makers of the language and its compiler to work within these constraints to create newer, more advanced language elements.
Considering the following code:
List names = Arrays.asList("1", "2", "3");
Stream lengths = names.stream().map(name -> name.length());
... It begins quite simply by loading the names var and invokes its .stream() method, but then it does something quite elegant. Instead of creating a new object that will wrap the Lambda function, it uses the new invokeDynamic instruction which was added in Java 7 to dynamically link this call site to the actual Lambda function.
aload_1 //load the names var
// call its stream() func
invokeinterface java/util/List.stream:()Ljava/util/stream/Stream;
//invokeDynamic magic!
invokedynamic #0:apply:()Ljava/util/function/Function;
//call the map() func
invokeinterface java/util/stream/Stream.map:
(Ljava/util/function/Function;)Ljava/util/stream/Stream;
InvokeDynamic is an instruction that was added in Java 7 to make the JVM less strict, and allows dynamic languages to bind symbols at run-time, vs. doing all the linkage statically when the code is compiled by the JVM.
The Lambda code
aload_0
invokevirtual java/lang/String.length:()
invokestatic java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
areturn

Lambda expressions don't get translated into anonymous inner classes, they use invoke dynamic that was introduced in Java 7 to execute functional methods. Check this out.
Do they violate OOP? I don't think that you should care. Lambdas make your code less verbose, easier to understand, and "easier" to parallelise. And thats what you should care about.
From Brain Goetz comment:
We don't get paid to write object-oriented programs or functional programs, we get paid to write working programs.

Lambda expression is compiled using invokedynamic bytecode.
Lambda implementation is stored in the same class file as a special private method.
Whether an object is created to invoke lambda depends on the situation. In the trivial cases lambda gets translated to a constant method handle.
To instantiate a lambda HotSpot creates an anonymous class that implements lambda's functional interface. This class does not belong to any ClassLoader.
See more details from the specification lead of Lambda Expressions JSR.

Related

Lambda expression or Method Reference? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I read in a book (Fischer's Java Closures and Lambda, Apress 2015) that method references are preferable to lambda expressions. From my point of view, the lambda expression is more easily understandable to developers who use other languages. Then why does it say the method reference is preferable? Is writing a lambda expression a bad practice in Java 8?
In the Lambda Best Practices section of Chapter 2, Fischer's book says:
As much as possible, use a method reference instead of a lambda. Method references are not only shorter and easier to read, but using method references will get you thinking directly about the methods as values. This is the code you need to excise from your codebase and your brain:
x -> it.do(x)
If you are naturally writing that code, then you still have not made the leap to thinking at the higher level of functional programming. Once you make that leap, it will become much easier to communicate and work with complex functions, because you will be thinking in types, not in values.
Although I mostly agree with the conclusion, I'm not sure I buy Fischer's line of reasoning. Method references are often, though not always, shorter than the written-out lambda. In the first part he says that method references will help you think about methods as values. OK, but then later he says things will become easier because you'll be thinking in types, not values. I'm not sure what that means.
It's possible to rewrite the example expression he gives as
it::do
That's certainly shorter than the original, but it's hard to generalize from a tiny example.
Here's my take on method references vs. written-out lambdas.
If there is a choice between using a lambda expression and a method reference, it is often the case that a method reference is preferable. But this is not a hard-and-fast rule, and there are likely to be circumstances where a lambda expression is preferable. It's also somewhat a matter of taste.
If you're familiar with lambda expressions from other languages, then lambda expressions in Java will probably be more immediately familiar than method references. However, I believe this to be a temporary state until you learn method references. Once they're more familiar, the advantages of method references can outweigh the initial unfamiliarity.
Consider this simple example of getting the lengths of strings:
List<String> list = ... ;
int[] lengths1 = list.stream().mapToInt(s -> s.length()).toArray();
int[] lengths2 = list.stream().mapToInt(String::length).toArray();
In this case, the size of the lambda expression is just about the same as the size of the method reference (in the number of characters). But notice that the method reference contains more type information. It tells the reader that the element type is String, which may be helpful in understanding a long pipeline. It is sometimes also helpful to the compiler, if it cannot infer the element type, as sometimes occurs in complex expressions.
Another point is that, using a method reference will often relieve you of the responsibility of coming up with a name for a formal parameter that's simply passed to another method. Naming is often important, but lambda formals are often "garbage" names like i x or s as in this example.
The method reference is a tiny bit more efficient, as it doesn't need to generate a static method that must be called through to get to the String.length() method. But this efficiency is rarely an important consideration.
Consider also this example, deliberately stripped of context:
(x, y) -> x + y
Is this string concatenation or numeric addition? If numeric, what type? Under the rules of the language, this must be known at compile time, otherwise it's an error. Although it might be clear to the compiler, sometimes this isn't very clear to the reader. Consider instead these method references:
String::concat
Integer::sum
Double::sum
Using a name for the operation in this case makes it very explicit to the reader about what is intended.

Why does Java 8 provide method references?

What is better in calling
names.stream().forEach(System.out::println);
Than
names.stream().forEach(n -> System.out.println(n));
Despite the fact you have to write less code? Are there any other advantages of introducing method references in Java 8?
Despite the fact you have to write less code? Are there any other advantages of introducing method references in Java 8?
Having to write less code is enough of an advantage to consider introducing a language feature. There is a similar feature in C#, called method groups, that makes it easier to write code that uses delegates. Lambdas are shorthand for anonymous classes, and anonymous classes could be considered shorthand for named classes. One could legitimately call them "syntactic sugar", yet all these features help you write less code.
In addition to letting you shorten the code, the feature has a potential of helping designers of Java compiler generate more efficient code. For example, it might be possible to avoid generating a brand-new type for each lambda wrapping a method reference.
Well, one advantage above just writing less code is, that the first example doesn't have to be aware of the parameters, as long as the implementation of that functional interface has the same signature (-> is correct) your code get's compiled.
If the signature of the the functional interface changes and the signature of the implementation changes analogously these changes only need to be applied there and not on that glue code.

What are the advantages of Lambda Expressions for multicore systems?

The Java Tutorials for Lambda Expressions says following:
This section discusses features included in Project Lambda, which aims
to support programming in a multicore environment by adding closures
and related features to the Java language.
My question is, what concrete advantages do I have with Lambda Expressions according to multicore systems and concurrent/parallel programming?
Parallelism is trivial to implement e.g. if you have a collection and you implement a lambda thus:
collection.map { // my lambda }
then the collection itself can parallelise that operation without you having to do the threading etc. yourself. The parallelism is handled within the collection map() implementation.
In a purely functional (i.e. no side effects) system, you can do this for every lambda. For a non-purely functional environment you'd have to select the lambdas for which this would apply (since your lambda may not operate safely in parallel). e.g. in Scala you have to explicitly take the parallel view on a collection in order to implement the above.
Some reference material:
You can read Maurice Naftalin's answer in Why are lambda expressions being added to Java.
Or you can read Mark Reinhold's answer in his article Closures for Java.
Reinhold also wrote, in his blog, a Closures Q&A which seems to address some of your questions.
And there is even an interesting article in JavaWorld about Understanding the Closures Debate.
With full respect to Java 8 lambda function and intents o developers I would like to ask: what is the new and why it is better than traditional interface/method function approach? Why it is better than (suppose) forEach(IApply) where:
IApply is interface
public interface IApply {
void exec(KEY key, VALUE value);
}
How it impedes to parallelism? At least implementation of IApply can be reused, inherited(extended), be implemented in static class.
The last argument is important after dozens of examples of errors of juniors that I seen, which miss that lambda code accesses this of outer class can be a cause of class stays in memory after distinct reference to it is null already.
From this point of view reference to static members of a class are much important (are analogies of a case of C# "delegate"s. And principally- from one hand- lambda is super encapsulation, from another one not reusable, and concurrently - violation of basic principles of OOD culture: free accessing master's members. From point of view of culture of programming- reverse to 70-th years of last century.
Functional programming? -I see, but why to mix is the OOP phenomena that Java is. OOD has wonderful pattern named Data-Behavior decoupling which elegantly provides the same possibilities? The argument - it is same like in Java Script ...nu, really! So give tools to embed Java Script in Java and write chunks of system in Java Script. So I still don't see really so much real benefits, as there are in wave of advertisement.

What's invokedynamic and how do I use it?

I keep hearing about all the new cool features that are being added to the JVM and one of those cool features is invokedynamic. I would like to know what it is and how does it make reflective programming in Java easier or better?
It is a new JVM instruction which allows a compiler to generate code which calls methods with a looser specification than was previously possible -- if you know what "duck typing" is, invokedynamic basically allows for duck typing. There's not too much you as a Java programmer can do with it; if you're a tool creator, though, you can use it to build more flexible, more efficient JVM-based languages. Here is a really sweet blog post that gives a lot of detail.
As part of my Java Records article, I articulated about the motivation behind Invoke Dynamic. Let's start with a rough definition of Indy.
Introducing Indy
Invoke Dynamic (Also known as Indy) was part of JSR 292 intending to enhance the JVM support for Dynamic Type Languages. After its first release in Java 7, The invokedynamic opcode along with its java.lang.invoke luggage is used quite extensively by dynamic JVM-based languages like JRuby.
Although indy specifically designed to enhance the dynamic language support, it offers much more than that. As a matter of fact, it’s suitable to use wherever a language designer needs any form of dynamicity, from dynamic type acrobatics to dynamic strategies!
For instance, the Java 8 Lambda Expressions are actually implemented using invokedynamic, even though Java is a statically typed language!
User-Definable Bytecode
For quite some time JVM did support four method invocation types: invokestatic to call static methods, invokeinterface to call interface methods, invokespecial to call constructors, super() or private methods and invokevirtual to call instance methods.
Despite their differences, these invocation types share one common trait: we can’t enrich them with our own logic. On the contrary, invokedynamic enables us to Bootstrap the invocation process in any way we want. Then the JVM takes care of calling the Bootstrapped Method directly.
How Does Indy Work?
The first time JVM sees an invokedynamic instruction, it calls a special static method called Bootstrap Method. The bootstrap method is a piece of Java code that we’ve written to prepare the actual to-be-invoked logic:
Then the bootstrap method returns an instance of java.lang.invoke.CallSite. This CallSite holds a reference to the actual method, i.e. MethodHandle.
From now on, every time JVM sees this invokedynamic instruction again, it skips the Slow Path and directly calls the underlying executable. The JVM continues to skip the slow path unless something changes.
Example: Java 14 Records
Java 14 Records are providing a nice compact syntax to declare classes that are supposed to be dumb data holders.
Considering this simple record:
public record Range(int min, int max) {}
The bytecode for this example would be something like:
Compiled from "Range.java"
public java.lang.String toString();
descriptor: ()Ljava/lang/String;
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokedynamic #18, 0 // InvokeDynamic #0:toString:(LRange;)Ljava/lang/String;
6: areturn
In its Bootstrap Method Table:
BootstrapMethods:
0: #41 REF_invokeStatic java/lang/runtime/ObjectMethods.bootstrap:
(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;
Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;
Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;
Method arguments:
#8 Range
#48 min;max
#50 REF_getField Range.min:I
#51 REF_getField Range.max:I
So the bootstrap method for Records is called bootstrap which resides in the java.lang.runtime.ObjectMethods class. As you can see, this bootstrap method expects the following parameters:
An instance of MethodHandles.Lookup representing the lookup context
(The Ljava/lang/invoke/MethodHandles$Lookup part).
The method name (i.e. toString, equals, hashCode, etc.) the bootstrap
is going to link. For example, when the value is toString, bootstrap
will return a ConstantCallSite (a CallSite that never changes) that
points to the actual toString implementation for this particular
Record.
The TypeDescriptor for the method (Ljava/lang/invoke/TypeDescriptor
part).
A type token, i.e. Class<?>, representing the Record class type. It’s
Class<Range> in this case.
A semi-colon separated list of all component names, i.e. min;max.
One MethodHandle per component. This way the bootstrap method can
create a MethodHandle based on the components for this particular
method implementation.
The invokedynamic instruction passes all those arguments to the bootstrap method. Bootstrap method, in turn, returns an instance of ConstantCallSite. This ConstantCallSite is holding a reference to requested method implementation, e.g. toString.
Why Indy?
As opposed to the Reflection APIs, the java.lang.invoke API is quite efficient since the JVM can completely see through all invocations. Therefore, JVM may apply all sorts of optimizations as long as we avoid the slow path as much as possible!
In addition to the efficiency argument, the invokedynamic approach is more reliable and less brittle because of its simplicity.
Moreover, the generated bytecode for Java Records is independent of the number of properties. So, less bytecode and faster startup time.
Finally, let’s suppose a new version of Java includes a new and more efficient bootstrap method implementation. With invokedynamic, our app can take advantage of this improvement without recompilation. This way we have some sort of Forward Binary Compatibility. Also, That’s the dynamic strategy we were talking about!
Other Examples
In addition to Java Records, the invoke dynamic has been used to implement features like:
Lambda Expressions in Java 8+: LambdaMetafactory
String Concatenation in Java 9+: StringConcatFactory
Some time ago, C# added a cool feature, dynamic syntax within C#
Object obj = ...; // no static type available
dynamic duck = obj;
duck.quack(); // or any method. no compiler checking.
Think of it as syntax sugar for reflective method calls. It can have very interesting applications. see http://www.infoq.com/presentations/Statically-Dynamic-Typing-Neal-Gafter
Neal Gafter, who's responsible for C#'s dynamic type, just defected from SUN to MS. So it's not unreasonable to think that the same things had been discussed inside SUN.
I remember soon after that, some Java dude announced something similar
InvokeDynamic duck = obj;
duck.quack();
Unfortunately, the feature is no where to be found in Java 7. Very disappointed. For Java programmers, they have no easy way to take advantage of invokedynamic in their programs.
There are two concepts to understand before continuing to invokedynamic.
1. Static vs. Dynamic Typing
Static - preforms type checking at compile time (e.g. Java)
Dynamic - preforms type checking at runtime (e.g. JavaScript)
Type checking is a process of verifying that a program is type safe, this is, checking typed information for class and instance variables, method parameters, return values, and other variables.
E.g. Java knows about int, String,.. at compile time, while type of an object in JavaScript can only be determined at runtime
2. Strong vs. Weak typing
Strong - specifies restrictions on the types of values supplied to its operations (e.g. Java)
Weak - converts (casts) arguments of an operation if those arguments have incompatible types (e.g. Visual Basic)
Knowing that Java is a Statically and Weakly typed, how do you implement Dynamically and Strongly typed languages on the JVM?
The invokedynamic implements a runtime system that can choose the most appropriate implementation of a method or function — after the program has been compiled.
Example:
Having (a + b) and not knowing anything about the variables a,b at compile time, invokedynamic maps this operation to the most appropriate method in Java at runtime. E.g., if it turns out a,b are Strings, then call method(String a, String b). If it turns out a,b are ints, then call method(int a, int b).
invokedynamic was introduced with Java 7.
The short answer is invokedynamic is a new opcode in the JVM that didn't exist prior to JAVA 7.
As far as reflection, within the context of this definition: Java Reflection is a process of examining or modifying the run time behavior of a class at run time., however, I believe more explanation is needed.
From the article below:
For example, reflection predates both collections and generics. As a
result, method signatures are represented by Class[] in the Reflection
API. This can be cumbersome and error-prone, and it is hampered by the
verbose nature of Java’s array syntax. It is further complicated by
the need to manually box and unbox primitive types and to work around
the possibility of void methods.
Method handles to the rescue
Instead of forcing the programmer to deal
with these issues, Java 7 introduced a new API, called MethodHandles,
to represent the necessary abstractions. The core of this API is the
package java.lang.invoke and especially the class MethodHandle.
Instances of this type provide the ability to call a method, and they
are directly executable. They are dynamically typed according to their
parameter and return types, which provides as much type safety as
possible, given the dynamic way in which they are used. The API is
needed for invokedynamic, but it can also be used alone, in which case
it can be considered a modern, safe alternative to reflection.
Quoting from Understanding Java method invocation with invokedynamic
These four are the bytecode representations of the standard forms of
method invocation used in Java 8 and Java 9, and they are
invokevirtual, invokespecial, invokeinterface, and invokestatic.
This raises the question of how the fifth opcode, invokedynamic,
enters the picture. The short answer is that, as of Java 9, there was
no direct support for invokedynamic in the Java language.
In fact, when invokedynamic was added to the runtime in Java 7, the
javac compiler would not emit the new bytecode under any circumstances
whatsoever.
As of Java 8, invokedynamic is used as a primary implementation
mechanism to provide advanced platform features. One of the clearest
and simplest examples of this use of the opcode is in the
implementation of lambda expressions.
So again, invokedynamic is a new opcode that allows for a new object reference type in JAVA, a Lambda.

Does Java need closures?

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)?
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?
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.
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.
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.
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
}
};
}
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.
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."
Well, most people who use the term "closure" actually mean "function object", and in this sense, function objects make it possible to write simpler code in certain circumstances such as when you need custom comparators in a sort function.
For example, in Python:
def reversecmp(x, y):
return y - x
a = [4, 2, 5, 9, 11]
a.sort(cmp=reversecmp)
This sorts the list a in reverse order by passing the custom comparison functoin reversecmp. The addition of the lambda operator makes things even more compact:
a = [4, 2, 5, 9, 11]
a.sort(cmp=lambda x, y : y - x)
Java does not have function objects, so it uses "functor classes" to simulate them. In Java you do the equivalent operation by implementing a custom version of the Comparator class, and passing that to the sort function:
class ReverseComparator implements Comparator {
public compare(Object x, Object y) {
return (Integer) y - (Integer) x;
}
...
List<Integer> a = Arrays.asList(4, 2, 5, 9, 11);
Collections.sort(a, new ReverseComparator());
As you can see, it gives the same effect as closures, but is clumsier and more verbose. However, the addition of anonymous inner classes obviates most of the pain:
List<Integer> a = Arrays.asList(4, 2, 5, 9, 11);
Comparator reverse = new Comparator() {
public Compare(Object x, Object y) {
return (Integer) y - (Integer) x;
}
}
Collections.sort(a, reverse);
So I would say that the combination of functor classes + anonymous inner classes in Java is sufficient to compensate for the lack of true function objects, making their addition unnecessary.
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.
When closures finally arrive in Java, I will gleefully get rid of all my custom comparator classes.
myArray.sort( (a, b) => a.myProperty().compareTo(b.myProperty() );
...looks a helluva lot better than...
myArray.sort(new Comparator<MyClass>() {
public int compare(MyClass a, MyClass b) {
return a.myProperty().compareTo(b.myProperty();
}
});
A few people have said, or implied, that closures are just syntactic sugar - doing what you could already do with anonymous inner classes and making it more convenient to pass parameters in.
They are syntactic sugar in the same sense that Java is syntactic sugar for assembler (that "assembler" could be bytecode, for sake of argument). In other words they raise they level of abstraction, and this is an important concept.
Closures promote the concept of the function-as-object to a first class entity - one that increases the expressiveness of code, rather than cluttering it with even more boilerplate.
An example that's close to my heart has already been mentioned by Tom Hawtin - implementing the Execute Around idiom, which is just about the only way to get RAII into Java. I wrote a blog entry on exactly that subject a couple of years ago when I first heard closures might be coming.
Ironically, I think the very reason that closures would be good for Java (more expressiveness with less code) may be what rattles many Java advocates. Java has a mindset of "spell everything out the long way". That and the fact that closures are a nod towards a more functional way of doing things - which I also see as a Good Thing, but may water down the pure OO message that many in the Java community hold dear.
I have been thinking a lot about the topic of this very interesting question in
the last few days. First of all, if I have understood correctly, Java already has
some basic notion of closures (defined through anonymous classes) but the new feature
that is going to be introduced is the support for closures based on anonymous functions.
This extension will definitely make the language more expressive but I am not sure
if it really fits with the rest of the language.
Java has been designed as an object-oriented language with no support for functional programming: Will the new semantics be easy to understand? Java 6 does not even have functions, will Java 7 have anonymous functions but no "normal" functions?
My impression is that as new programming styles or paradigms like functional
programming become more popular, everyone wants to use them in their
favourite OOP language. This is understandable: one wants to continue to use
a language they're familiar with while adopting new features. But in this way
a language can become really complex and lose coherence.
So my attitude at the moment is to stick to Java 6 for OOP (I hope Java 6 will still
be supported for a while) and, in case I really get interested in doing OOP + FP,
to take a look at some other language like Scala (Scala was defined to be multi-
paradigm from the beginning and can be well integrated with Java) rather than switching
to Java 7.
I think Java owes its success to the fact that it combines a simple language with very
powerful libraries and tools, and I do not think that new features like closures will
make it a better programming language.
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.
The State of Lambda: in the first page or two this article attempts to answer the question presented here. Although I still found it short in arguments, but is is full of examples.
The State of Lambda - Libraries Edition: this is also very interesting because it covers advantages like lazy evaluation and parallelism.
The Translation of Lambda Expressions: which basically explains the desugaring process done by the Java compiler.
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.
Closures in an imperative language (examples: JavaScript, C#, the forthcoming C++ refresh) are not the same as anonymous inner classes. They need to be able to capture modifiable references to local variables. Java's inner classes can only capture local final variables.
Almost any language feature can be criticised as non-essential:
for, while, do are all just syntactic sugar over goto/if.
Inner classes are syntactic sugar over classes with a field pointing to the outer class.
Generics are syntactic sugar over casts.
Exactly the same "non-essential" argument should have blocked the inclusion of all the above features.
Java Closure Examples
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.
What about readability and maintainability...one-liner closures are harder to understand and debug, imo
Software has looong life and you can get people with rudimentary knowledge of the language to maintain it...So spread out logic better than one-liners for easy maintenance...You generally don't have a software star looking after software after its release...
You might want to look at Groovy, a language that's mostly compatible with Java, and runs on the JRE, but supports Closures.
The lack of binding in anonymous function [i.e. if the variables (and method arguments if there is an enclosing method) of the outer context are declared final then they are available but not otherwise], I don't quite understand what that restriction actually buys.
I use "final" profusely anyways. So, if my intent was to use the same objects inside the closure, I would indeed declare those objects final in the enclosing scope. But what would be wrong in letting the "closure [java a.i.c.]" just get a copy of the reference as if passed via a constructor (well that in fact is how it is done).
If the closure wants to overwrite the reference, so be it; it will do so without changing the copy that the enclosing scope sees.
If we argue that that would lead to unreadable code (e.g. maybe it's not straight-forward to see what the object reference is at the time of the constructor call for the a.i.c.), then how about at least making the syntax less verbose? Scala? Groovy?

Categories