41

There is a new hype with the long awaited lambda expressions in Java 8; every 3 day another article appears with them about how cool they are.

As far as I have understood a lambda expression is nothing more than an anonymous inner class with a single method (at least at the byte-code level). Besides this it comes with another nice feature - type inference but I believe the equivalent of this can be achieved with generics on some level (of course not in such a neat way as with lambda expressions).

Knowing this, are lambda expressions going to bring something more than just a syntactic sugaring in Java? Can I create more powerful and flexible classes or other object-oriented constructs with lambda expressions that aren't possible to be built with current language features?

10
  • 33
    When a language is turing-complete, every added feature could theoretically be described as "syntactic sugar".
    – Philipp
    Commented Apr 16, 2013 at 9:38
  • 38
    @Philipp: That's wrong. The defining characteristic of syntactic sugar is that desugaring is purely local and does not change the global structure of the program. There are lots of features that cannot be implemented with just local transformations. For example, if you take a hypothetical language that is identical to Java but with proper tail calls, it would not be possible to desugar tail calls to "pure" Java without globally transforming the entire program. Commented Apr 16, 2013 at 10:32
  • 2
    @Philipp: Unfortunately there is only one upvote for comments, otherwise I would upvote Joerg's comment 1000 times. No, it is wrong that any feature can be described as syntactic sugar. Syntactic sugar does not add new semantics. In fact, AFAIK the proposed Java lambdas are NOT syntactic sugar for special anonymous inner classes because they have different semantics.
    – Giorgio
    Commented Apr 16, 2013 at 15:30
  • 1
    @Giorgio: and what different semantics do they have?
    – user102008
    Commented Apr 17, 2013 at 5:41
  • 2
    @Giorgio: Yes, but the conversion of this into OuterClass.this is part of the process of de-sugaring lambda expressions into anonymous class.
    – user102008
    Commented Apr 17, 2013 at 9:10

5 Answers 5

48

tl;dr: while it's mostly syntactic sugar, that nicer syntax makes lots of things practical that used to end in endless, unreadable lines of braces and parentheses.

Well, it's actually the other way around as lambdas are much older than Java. Anonymous inner classes with a single method are (were) the closest Java came to lambdas. It's an approximation that was "good enough" for some time, but has a very nasty syntax.

On the surface, Java 8 lambdas seem to be not much more than syntactic sugar, but when you look below the surface, you see tons of interesting abstractions. For example the JVM spec treats a lambda quite differently from a "true" object, and while you can handle them as if they where objects, the JVM is not required to implement them as such.

But while all that technical trickery is interesting and relevant (since it allows future optimizations in the JVM!), the real benefit is "just" the syntactic sugar part.

What's easier to read:

myCollection.map(new Mapper<String,String>() {
  public String map(String input) {
    return new StringBuilder(input).reverse().toString();
  }
});

or:

myCollection.map(element -> new StringBuilder(element).reverse().toString());

or (using a method handle instead of a lambda):

myCollection.map(String::toUpperCase);

The fact that you can finally express in a concise way which would previously be 5 lines of code (of which 3 are utterly boring) brings a real change of what is practical (but not of what is possible, granted).

7
  • 1
    I totally agree with the syntax sugaring part; my question was about new object-oriented constructs only possible with lambda expressions; after all Java is an object-oriented language. Think in comparison with generics, and how they bought much flexibility in Java, flexibility unachievable without them.
    – Random42
    Commented Apr 16, 2013 at 9:38
  • 8
    @m3th0dman: actually generics added no new abilities. A List could hold any object, a List<String> can "only" hold strings. Generics added a restriction (and the option to formalize restrictions!), not an addition in power. Pretty much everything since Java 1.1 has been syntactic sugar. And that's not necessarily a bad thing. Commented Apr 16, 2013 at 9:40
  • 3
    @m3th0dman: Actually generics added no new abilities, because in Java they are just a syntactic sugar. A List<String> is just a List with cast to String added around some return values. Nevertheless they are extremely useful and made the language much more convenient to write in. Lambdas are similar case.
    – Jan Hudec
    Commented Apr 16, 2013 at 9:48
  • 4
    Actually it's far more than just syntactic sugar. Much of the functionality is implemented as a first class citizen in the JVM through use of the invokedynamic bytecode + some pretty hefty advances to the Type inference system. It's not implemented as anonymous inner classes. Commented Apr 16, 2013 at 9:58
  • 2
    @zengr: see here, for example. From that perspective, they are true objects, but a lambda expression is not an instantiation expression. It’s just a request to get an appropriate object in whatever way. From the language’s perspective, lambda expressions are not objects, but something that will be converted to an instance of the target type in a JRE implementation specific way.
    – Holger
    Commented Nov 8, 2016 at 14:24
14

For Java, yes, it's nothing more than a better way of creating an anonymous inner class. This is because of the fundamental decision in java that every bit of byte code has to live within a specific class, which cannot be changed now after decades of legacy code to consider.

However, that is not what lambda expressions really are about. In formalisms where they are native concepts rather than a jump-on-the-bandwagon contortion, lambdas are fundamental building blocks; both their syntax and people's attitude towards them are very different. The example of an anonymous recursive function created purely out of lambdas in Structure and Interpretation of Computer Programs is capable of changing your entire conception of computation. (However, I'm pretty certain that way of learning to program is just to esoteric ever to become a mainstream success story.)

2
  • 1
    Learning that everything can be implemented in terms of lambdas is very instructive and not "esoteric" in my opinion. (However, I guess most "coders" don't care about interesting CS theory.) That doesn't mean that lambdas is special; it just means that lambdas are one type of universal construct. There are others, like SKI combinators. Lambdas are fundamental building blocks in functional paradigms, but maybe something else can be fundamental in another paradigm.
    – user102008
    Commented Apr 16, 2013 at 21:43
  • +1 for "jump-on-the-bandwagon contortion": I often wonder why some languages keep changing to mimic other popular languages and why programmers put up with it. I like lambdas and use them a lot in Scala, Lisp, Haskell, but in Java or C++ they feel like an afterthought bolted onto the language just because they have become popular in other languages.
    – Giorgio
    Commented Jun 23, 2016 at 20:42
2

Joachim Sauer already did a good job answering you question but only hinted at something I regard as important. Since Lambdas are no classes they are also not compiled as such. All anonymous inner classes result in the creation of a .class file which in turn has to be loaded by the ClassLoader. So using Lambdas instead does not only make your code more beautiful, it also reduces the size of your compiled code, the memory footprint of your ClassLoader, and the time it takes to transfer the bits from your hard drive.

1

Yes, it is just a syntactic sugar, in the sense that anywhere you write a lambda, you can re-write that expression as an anonymous inner class expression with one method, where the class implements the functional interface inferred for the lambda's context, and it would be exactly equivalent semantically. And you can do this by simply replacing the lambda expression with the anonymous class expression, without changing any other expression or line of code.

7
  • 1
    why downvote? what I said is completely correct
    – user102008
    Commented Apr 17, 2013 at 5:40
  • 1
    What you write sounds a reasonable proposal for Java lambdas but this proposal was discarded in favour of a different one (doanduyhai.wordpress.com/2012/07/12/…).
    – Giorgio
    Commented Apr 17, 2013 at 8:50
  • 1
    @Giorgio: I am not "proposing" anything. What, exactly, do you disagree with what I said? Yes, the inside of the expression will look different, e.g. we will add a method, and yes, this will need to be converted to OuterClass.this. That does not contradict what I said -- every lambda expression can be converted into a semantically-equivalent anonymous class expression without altering anything outside of that expression. I didn't say that the inside wouldn't change.
    – user102008
    Commented Apr 17, 2013 at 9:17
  • 4
    What you said is incorrect. The semantics of lambda and anon inner classes are not exactly the same (though they are similar). Off the top of my head, the meaning of meaning of this changes; and anon inner classes always result in a new instance of an object, whereas a lambda might or might not. Commented Apr 17, 2013 at 18:52
  • 1
    @StuartMarks: No, you didn't read my answer. I didn't say that each of them can do everything the other does. I said that a lambda has an equivalent anonymous class that is semantically the same. As I already said in comments, this in lambda is a part of the syntactic sugar, and is not a difference in semantics. And about differences in implementation, implementation != semantics. About differences in object identity; object identity is extremely tangential to the functionality of lambdas; nobody checks the object identity of lambdas/anon classes anyway because it is not useful.
    – user102008
    Commented Apr 17, 2013 at 19:24
-1

No. They are not.

Another way to put it is lambdas are an un-object-oriented, however concise, way to achieve the same thing that an anonymous class or, my preference, inner class would achieve in an object-oriented way.

2
  • 1
    Functional programming can be totally orthogonal to Object Oriented programming (see: Scala and F#). This reads like the opinion of somebody who simply dislikes functional programming on principle.
    – KChaloux
    Commented Jun 2, 2014 at 20:13
  • 2
    @KChaloux - Not a functional programming hater. The answer is written by someone who prefers to have a hammer AND a screwdriver rather than a Hammerdriver. OO Programming is a good paradigm, as is functional programming. My preference in a language is for it to be clear about its intentions. Lambdas I feel muddy the otherwise OO nature of Java. Java was not designed to be a functional language. Human beings need structure to do their best work. Commented Jun 2, 2014 at 20:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.