Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 lambda expression and first-class values

Are Java 8 closures really first-class values or are they only a syntactic sugar?

like image 784
xdevel2000 Avatar asked Mar 05 '13 10:03

xdevel2000


People also ask

Can we use lambda expression with class?

Lambda expressions are very powerful and can replace many usages of anonymous class but not all. An anonymous class can be used to create a subclass of an abstract class, a concrete class, and can be used to implement an interface in Java. It can even add state fields.

Are lambdas first class objects?

No, not first class functions. Lambda expression are wrapped in a interface, and some syntatic sugar applied for brevity.

Are functions first class citizens in Java?

Functions are first class citizen means you can pass function anywhere as if it's a variable.

Does Java 1.8 support lambda expressions?

Lambda Expressions were added in Java 8.


2 Answers

I would say that Java 8 closures ("Lambdas") are neither mere syntactic sugar nor are they first-class values.

I've addressed the issue of syntactic sugar in an answer to another StackExchange question.

As for whether lambdas are "first class" it really depends on your definition, but I'll make a case that lambdas aren't really first class.

In some sense a lambda wants to be a function, but Java 8 is not adding function types. Instead, a lambda expression is converted into an instance of a functional interface. This has allowed lambdas to be added to Java 8 with only minor changes to Java's type system. After conversion, the result is a reference just like that of any other reference type. In fact, using a Lambda -- for example, in a method that was passed a lambda expression as parameter -- is indistinguishable from calling a method through an interface. A method that receives a parameter of a functional interface type can't tell whether it was passed a lambda expression or an instance of some class that happens to implement that functional interface.

For more information about whether lambdas are objects, see the Lambda FAQ Answer to this question.

Given that lambdas are converted into objects, they inherit (literally) all the characteristics of objects. In particular, objects:

  • have various methods like equals, getClass, hashCode, notify, toString, and wait
  • have an identity hash code
  • can be locked by a synchronized block
  • can be compared using the == and != and instanceof operators

and so forth. In fact, all of these are irrelevant to the intended usage of lambdas. Their behavior is essentially undefined. You can write a program that uses any of these, and you will get some result, but the result may differ from release to release (or even run to run!).

Restating this more concisely, in Java, objects have identity, but values (particularly function values, if they were to exist) should not have any notion of identity. Java 8 does not have function types. Instead, lambda expressions are converted to objects, so they have a lot baggage that's irrelevant to functions, particularly identity. That doesn't seem like "first class" to me.

Update 2013-10-24

I've been thinking further on this topic since having posted my answer several months ago. From a technical standpoint everything I wrote above is correct. The conclusion is probably expressed more precisely as Java 8 lambdas not being pure (as opposed to first-class) values, because they carry a lot of object baggage along. However, just because they're impure doesn't mean they aren't first-class. Consider the Wikipedia definition of first-class function. Briefly, the criteria listed there for considering functions first-class are the abilities to:

  • pass functions as arguments to other functions
  • return functions from other functions
  • assign functions to variables
  • store functions in data structures
  • have functions be anonymous

Java 8 lambdas meet all of these criteria. So that does make them seem first-class.

The article also mentions function names not having special status, instead a function's name is simply a variable whose type is a function type. Java 8 lambdas do not meet this last criterion. Java 8 doesn't have function types; it has functional interfaces. These are used effectively like function types, but they aren't function types at all. If you have a reference whose type is a functional interface, you have no idea whether it's a lambda, an instance of an anonymous inner class, or an instance of a concrete class that happens to implement that interface.

In summary, Java 8 lambdas are more first-class functions than I had originally thought. They just aren't pure first-class functions.

like image 90
Stuart Marks Avatar answered Oct 04 '22 10:10

Stuart Marks


Yes, they are first class values (or will be, once Java 8 is released...)

In the sense that you can pass them as arguments, compose them to make higher order functions, store them in data structures etc. You will be able to use them for a broad range of functional programming techniques.

See also for a bit more definition of what "first class" means in this context:

  • http://en.wikipedia.org/wiki/First-class_citizen
like image 34
mikera Avatar answered Oct 04 '22 10:10

mikera