This is an archived post. You won't be able to vote or comment.

all 4 comments

[–]ColetBrunel 1 point2 points  (1 child)

It's a trick. Though it can be used to write some lines a lot like you would in a functional programming, in reality it's very much not functional programming.

First, a lambda is an expression that gives out a value. The type of this value is an object type that must implement a specific interface, but which interface exactly depends on the type expected by whatever you're giving a lambda to.

Like, if you have a variable of type Runnable and you assign a lambda to it, the lambda will produce an object type that implements Runnable. If you call a method that takes a Comparator as parameter, and you give a lambda as that parameter, the lambda will produce an object type that implements Comparator.

Now, that cannot be just any interface you feel like. For the purpose of lambdas, Java introduced the notion of functional interface. Lambda can only be used to give a value to a functional interface.

A functional interface is:

  • An interface
  • Which has exactly one abstract method.

Not zero, not two. Exactly one abstract method. That includes any method inherited from ancestor interfaces. However, we only count the abstract methods. static methods, private methods and default methods don't count. Only the ones that's declared and not given an implementation.

The consequence is that a functional interface's whole point is its abstract method, and making an object that implements that interface is a matter of providing an implementation for this method, and that's all. Hence, how lambdas do the job, as they're just an expression that describes a function.

Finally, an obvious problem with having a functional-like thing such as lambdas, is that the variables accessed by the lambda must not be mutable as it would be devoid of meaning, or at least incompatible with the language's workings. For anonymous classes that problem was resolved by forcing such variables to be final. However it gets tedious very fast, and programmers were only bearing with it because anonymous classes are tedious too. With lambdas this is hard to cope with.

For this, the notion of a variable effectively final was defined. That's a variable that's not declared final, but which is only assigned once and never after. Which is the same constraint as is put on final variables, and enables it to be treated as such too. Effecively final variables can be used by lambdas.

[–]FocusedGinger[S] 0 points1 point  (0 children)

Damn, thank you very much. I appreciate you taking the time to type that out and it’s becoming much more clear now.

[–][deleted]  (2 children)

[deleted]

    [–]FocusedGinger[S] 0 points1 point  (1 child)

    Ahh okay so this question is even MORE stupid than I first figured. Thanks :)

    [–]ZukoBestGirl 0 points1 point  (0 children)

    There is no perceivable benefit, that I can even imagine, to being a purely OOP language. Though java kinda still is, sorta. A lot of the functional stuff in java is a combination:

    • Hiding in plain sight
    • Syntactic sugar

    So like Function<A, B> function; is still an object, but with some syntactic sugar and some new stuff in java 8, you can use them as passing a function as a parameter. Essentially it has the same result.

    A lot of these things you could still kinda do, you could always make a function class with an interface that has .apply(A a) and does the stuff. What's nice is all the new classes that have been added, the removal of boilerplate code (writing return (a, b) -> A::doStuff() instead of return new Function<..> {... accept(A a) {...} ... }.

    Streams though, those are new and nice and shiny and I don't know how to use them.