Concepts / Functional Interfaces in Java

Functional Interfaces in Java

A Java lambda expression is written with the arrow operator ->, with a dummy parameter on the left and the computing expression on the right.

  • Programming

Why a Lambda Looks Like a First-Class Function

Many learners meet Java lambda expressions and quickly conclude that Java now treats functions the way languages such as Lisp or JavaScript do: as ordinary values that can be stored, handed around, and invoked by name. The conclusion feels natural. A lambda expression is a compact way to write down a function, and it can be assigned to a variable, so it seems reasonable that the variable would then behave like a function.

This section is about why that conclusion is not quite right, and what Java actually does instead. The source raises the question directly: are functions now first-class in Java? Its honest answer is that it is not sure they are, because some things that are possible in other languages are not possible in Java. The misconception is worth taking seriously precisely because the surface of Java lambdas looks so much like first-class functions.

Keep one concrete case in mind as you read. A lambda expression for squaring is assigned to a variable named sqr. The question is whether that variable can then be used the way a function is used. You will return to this case several times.

Reading the Arrow Form

A Java lambda expression is built around a single operator, the arrow written as ->. The arrow is what marks the whole construction as a lambda expression. Everything to the left of the arrow is the dummy parameter for the function, and everything to the right of the arrow is the expression that computes the function's value.

xdummy parameter, left ofthe arrow->arrow operatorx * xcomputing expression, rightof the arrowplaceholder for inputdescribes the result
Which part is the dummy parameter list, where does the arrow sit, and which part is the computing expression that gets evaluated?
Code walkthrough
(squaring example, illustrative)
x -> x * x
  1. 1
    The left side, x, does not hold a value yet. It is a stand-in for whatever input the function later receives.
  2. 2
    The arrow separates the placeholder from the description of work to be done with it.
  3. 3
    The right side describes the computation. For a squaring function, it multiplies the placeholder by itself.
  • x is the dummy parameter: a placeholder that names the input the function will receive
  • -> is the arrow operator that marks this as a lambda expression
  • x * x is the computing expression that multiplies the placeholder by itself

The word dummy matters. The parameter is not a variable with a value you can read on its own; it is a placeholder that describes the shape of the input. Read the lambda as a recipe: take one input, call it x, and produce x times x.

Tracing a Lambda Assigned to sqr

The source gives a concrete case. The squaring expression can be assigned to a variable named sqr. Follow the steps below to see what the variable actually holds and what happens when you try to use it.

Worked example

Assigning a lambda to sqr and attempting a call

A squaring lambda is assigned to a variable named sqr. Can the program then write sqr(42) the way it would call a function?

  1. 1
    Write the lambda

    The expression x -> x * x describes a squaring function using the arrow form: a dummy parameter on the left, a computing expression on the right.

  2. 2
    Assign it to a name

    The lambda is placed where Java expects a value, in a variable named sqr. Java is strongly typed, so the variable must be declared with a type. An illustrative declaration is: SomeFunctionalType sqr = x -> x * x; where SomeFunctionalType stands in for the functional interface type that the source introduces next.

  3. 3
    Attempt the call

    Writing sqr(42) treats sqr like a free-standing function. The source states that Java does not permit this, even though the assignment itself was legal.

  4. 4
    Identify what is missing

    The assignment supplied the expression but not the type that tells Java what kind of value sqr refers to. That missing type information is what makes the call illegal.

Result

The assignment succeeds, but sqr(42) is not permitted. The variable holds a lambda-typed value, not a callable function name.

sqrvariable namex -> x * xlambda expression valueFunctional interfacetype that fits the valueholdsdeclared with type
When a variable holds a lambda, what does it reference, and what supplies its type?

Why Strong Typing Blocks the Call

The reason sqr(42) fails is strong typing. Java is a strongly typed language, which means that to have a variable named sqr, you must declare that variable and give it a type. The question then becomes: what type fits a value that is a function? The source's answer is a construct called a functional interface. The source names the type that lambda expressions use in Java as a functional interface, and says its role is to supply the type a lambda needs when it is held in a variable or passed around.

Definition

Functional interface: the type that lets Java accept a lambda expression as a value. A lambda is written in the arrow form, and the functional interface is the declared type that makes that form legal to store in a variable or pass as an argument.

The arrow tells you how the function is written. The type tells Java what kind of value the name refers to. A plain assignment supplies the first but leaves the second unsettled, and that is why a call written as if sqr were a function has no legal meaning in Java. The details of how a functional interface is declared are the subject of the next section of the source, so this article does not go further into them.

A lambda expression can appear in three places: as an actual parameter passed to a subroutine, as an assigned value, or as a returned value. In each case it is a value written into a place where Java expects a value. None of these three placements, by itself, makes functions first-class in Java.

Function valuestored and called by nameLambda valuestored in a typed variablef(42)call is permittedsqr(42)call is not permitted
How does Java's model, a lambda wrapped in an interface-typed value, differ from a language where a function value can be stored and called directly?

Mistakes Learners Make with Lambdas

  • Common mistake

    Concluding that Java has first-class functions because lambdas can be assigned to variables

    What it looks like

    A learner assigns x -> x * x to sqr and expects sqr(42) to work, the way it would in a language with first-class functions.

    Why it fails

    Assigning a lambda to a variable does not make Java treat that variable as a callable function. The source says Java does not permit sqr(42) for this variable.

    Do this instead

    Treat the lambda as a value that needs a type. Ask what type the variable has before you ask whether it can be called.

  • Common mistake

    Reading the dummy parameter as a variable with a value

    What it looks like

    A learner tries to use x on its own, outside the lambda, expecting it to hold 42.

    Why it fails

    The dummy parameter is a placeholder naming the input the function will receive. It is not a standalone variable with a value.

    Do this instead

    Read the left side as the name of the input shape and the right side as the computation performed on that input.

  • Common mistake

    Ignoring the type when reasoning about the lambda

    Why it fails

    Java is strongly typed, so the variable must be declared with a type. The type is what the functional interface supplies, and leaving it out leaves the question of what the name refers to unanswered.

    Do this instead

    When you read any lambda assignment, identify both the arrow expression and the declared type of the variable that holds it.

  • Common mistake

    Assuming that the arrow form alone is enough to make a lambda usable everywhere a function value would be

Practice Predicting the sqr Variable

What do you think happens?

A squaring lambda is assigned to a variable named sqr. Can you write sqr(42) and have Java compute 42 times 42?

  • Yes, because sqr now holds a function that can be called by name

  • No, because sqr is a variable holding a lambda value, and Java does not allow it to be called like a function

Reveal answer
Answer:

No, because sqr is a variable holding a lambda value, and Java does not allow it to be called like a function.

The source states that assigning a lambda to a variable does not make Java treat that variable as callable, so sqr(42) is not permitted. The reason is strong typing: the variable needs a type, and the functional interface supplies that type.

EASY

Take the lambda y -> y + y. Identify the dummy parameter, the arrow operator, and the computing expression. Then explain in one sentence why assigning it to a variable named doubler would still not let you write doubler(5) as a plain function call in Java.

Hints
  • The dummy parameter is the placeholder on the left of the arrow.
  • Connect your sentence to strong typing: what must the variable have before Java can accept it?

Key Takeaways

  • A Java lambda expression is written with the arrow operator ->, with a dummy parameter on the left and the computing expression on the right.
  • Assigning a lambda to a variable does not make Java treat that variable as callable, so a call such as sqr(42) is not permitted.
  • Java is strongly typed, so a variable must be declared with a type; the functional interface supplies the type that fits a lambda value.
  • A lambda can be passed as an argument, assigned to a variable, or returned, but none of these alone makes functions first-class in Java.