Fundamentals

Default Methods

Collections

Idioms and Techniques

Design Rationale

Advanced Questions

Why is there no shorthand syntax for invoking a lambda?

A lambda expression provides a concise, shorthand syntax for implementing the single abstract method of a functional interface. Why isn’t there a corresponding shorthand for invoking the lambda? For example, the default implementation (simplified for clarity) of Iterable.forEach is as follows:

default void forEach(Consumer<T> action) {
    for (T t : this) {
        action.accept(t);
    }
}

Why is the call to action.accept() necessary? Why couldn’t one just invoke the lambda by writing action() ?

One reason is that at the site where the lambda expression is written, the functional interface that’s the target of the lambda is quite special. It has a single abstract method, so any lambda expression present must be an implementation of that abstract method.

On the calling side, though, all the caller gets is a reference to an instance of the functional interface. There’s no lambda visible at this point, therefore there is nothing special about the (formerly) abstract method the lambda has implemented. That method could be one of many methods, including default methods, that could be invoked through that interface. One could inspect the interface and invoke the single formerly-abstract method, but that would be a fairly obscure special case.

A deeper reason is that the namespaces for method names and variable names are distinct. That is, a method can have the same name as a field (or a local variable) without any shadowing or ambiguity. Whether an identifier is a method or a variable is determined by its syntactic position. Consider the situation that would occur if the Iterable class also had an action method:

void action(T t) { ... }

default void forEach(Consumer<T> action) {
    for (T t : this) {
        action.accept(t);
    }
}

In this code, action is clearly a variable, since it is operated upon by the . (dot) operator. If the language were to allow action() to invoke the lambda, this would introduce an ambiguity: would it invoke the lambda, or would it invoke the method? Thus, the obvious lambda invocation syntax cannot be used, and a different invocation syntax would have to be created in order to invoke a lambda. This, combined with the somewhat obscure semantics of which method “invoking a lambda” will invoke (as opposed to the straightforward semantics of ordinary method invocation) make it not very valuable to create a special purpose syntax for lambda invocation.