What is a Lambda Expression?

Java 8 will include Lambda expressions. They’re being added in as part of Project Lambda. But what is a Lambda expression? The term “Lambda” comes from mathematics, where it’s called lambda calculus. In programming, a Lambda expression (or function) is just an anonymous function, i.e., a function with no name. In fact, some Lambda expressions don’t even have a function body.

LambdaWhy are Lambda expressions being added to Java? It’s because they encourage a functional style of programming, and it’s clear that LINQ in C# is popular and successful in making software simpler and more robust. Also, in the Java world Scala in particular has become popular for Java developers and is an object oriented/functional programming hybrid. Incorporating elements of functional programming like Lamndas into Java helps move it a little closer toward Scala.

Here’s a simple Lambda expression in Java. It’s the same in C# because the new Lambda syntax in Java is virtually identical to the one used in C#.

(a,b) -> a + b

The two variables are parameters. The arrow sign is the real key to this. If you see one, you know it’s a Lambda expression. This one evaluates a + b. Note that the type of a and b is inferred by the compiler.

Or you could specify it explicitly:

(int a, intb) -> a + b

Many languages support anonymous functions. They were originally in Lisp in the 1950s but many modern ones – such as JavaScript, C# and Haskell — support them. In JavaScript for example:

alert((function(x){
return x*3.14159;
})(5));

That will display the value 5 * pi. Note the lack of function name.

More formally, a Lambda expression is defined by a comma-separated list of values followed by an arrow ( -> ) in the body of the expression. The values have to be surrounded by brackets if there’s more than one value. Otherwise, the brackets are optional.

Here’s an example:

a -> a * 5
() -> TriggerAlarm() // calls the method TriggerAlarm()

What Use Are Lambdas?

Well clearly they’re useful for simplifying your code. Lambdas work with objects, so you can call methods via them. Or on collections.

A typical use is to do something to elements of a collection. Even better, we can apply some sort of a test (called a predicate) so we don’t do the operation on every member of the collection — just those that are selected for inclusion by the predicate function.

For example, let’s say we want to sack all employees whose appraisal score was an F. This is how you might do it in Java. The fail char will be “F”.

public void SackEmployees( List staff, char fail ) {
for (Employee staffmember : staff ) {
if (staffmember.getAppraisal() == fail) {
{
staffmember.doTerminate();
}
}

As code goes it’s OK, but it’s very closely coupled, so adding other functionality needs code changing. You might want to make it more general by separating the appraisal test into a different class.

public void SackEmployees( List staff, AppraisalTest test ) {
for (Employee staffmember : staff ) {
if (if test.failed(staffmember)) {
{
staffmember.doTerminate();
}
}

The AppraisalTest could be defined as an interface, so you create a class that implements this interface. That makes it possible to come up with all sorts of other tests, e.g. employeeFailedDrugTest, employeeWasDrunk. The interface looks something like this:

interface JobTerminationTest { boolean test (Employee e); }

Having defined that, we can then declare classes that implement it such, as FailedAppraisalTest.
So we’d rewrite the appraisal test as a simple class:

class FailedAppraisalTest implements JobTerminationTest {
public boolean test (Employee e) {
return e.getAppraisal() == fail;
}
}

Now we can call SackEmployees like this:

sackEmployees( allstaff, new FailedAppraisalTest());

But we can use a Lambda expression to improve SackEmployees further and avoid the need for a separate class.

public void SackEmployees( List staff, AppraisalTest selectiontest ) {
List staff, Predicate(Employee) selectiontest) {
for (Employee staffmember : staff ) {
if (selectiontest.failed(staffmember) {
{
staffmember.doTerminate();
}
}
}
}


sackEmployees( allstaff, e -> e.getAppraisal() == fail);

So we no longer need to specify the class. Instead, we’ll use a functional interface. But what exactly is that?

Functional Interfaces

I did a big jump earlier introducing functional interfaces such as Predicate above. In the package Java.util.function there are large collections of functional interfaces that provide target types. Many are compatible with lambdas. A functional interface is an interface with just one abstract method.

Popular ones used with Lambda expressions include

  • Predicate<T> – It takes T as input and returns a boolean.
  • Function<T,R> – T is the input – R is the output
  • Supplier<T> – No Input but returns an object of type T.
  • Consumer<T> – Takes T as input but returns nothing.

This is only the start– in a future article, I’ll demonstrate use of other functional interfaces with Lambdas.

In the meantime, if you’re interested in Lambdas but don’t want to move up to Java 8, there’s an ingenious solution offered for Java versions 5-7. RetroLambda, developed by Esko Luontola.

Comments

  1. BY Bud says:

    Call me old school, but I do not find this syntax easy to read and understand. Since code is read at least 70% of the time, code should be clear and straightforward as to its meaning and execution. To me, it is a giant leap backwards in IT development if I have to think about the syntax of the code rather than what that code is attempting to accomplish.

Post a Comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>