miércoles, 17 de noviembre de 2021

Pros and cons of using Java Lambda expressions instead of traditional methods invocation.

 

When I discovered object-oriented programming. I was very happy with the very natural way of calling methods that were members of an object. Before, we write procedures or functions in structured languages like C or Pascal, but these procedures belonged to no one. It was like asking something to the wind. Java and or others object-oriented languages model better the real world. In an organization or in a real scenario, actions are performed by someone (a person, an area, or even an abstract thing, but by someone), and/or on some other actor, some other thing.

Java appeared in a nice moment for computing. It was been used for every imagined human activity, personal computers were common and we had not size limits for code or identifiers because of the big hard disks and memories available, (measured gigabytes and megabytes, respectively, no kidding). Some programmers like me started to write very understandable programs with significant identifiers and a lot of lines of code. But when we write classes with thousands of lines of code, maybe it cannot be easy for another programmer to navigate within it.

Then, someone turned to the functional programming, a declarative programming style closer to the pure mathematical functions style and Lambda expressions were introduced to Java. This can allow a programmer to write on a single, or at most in a few lines of code, what otherwise will need several sentences in Java traditional style. Let’s take a closer look.

As traditional Java was based on classes, every action must be carried by an instance of a class, an object, as a method. Then, if we want that action to be performed, we must first instantiate the class, and call the method with the corresponding input parameters, and read the returned result. This is very useful when we want to model some real-world entity like a person or a human-invented thing like an accounting invoice. But if we just want to perform a common action that do not belong to no object, we have the option of an abstract class but, besides the instantiation, we need the same steps and almost the same quantity of code.

With the purpose of enabling Java programmers for writing more compact, and more readable code, version 8 incorporated Lambda expressions as a way to allow functional programming style. How it works? Let’s see the following case.

Say we need to write a program for adding to integer numbers and print result on console. We can write a very simple code like this:



 Code contains a class Calculator with just one method for now, Add. When we want to access to this functionality, we need to instantiate the class and call the method. Very object-oriented, but inflexible too. If we want to add or change its functionality, we need to write another method or to modify the existing one. If we do not have access to Calculator class source code, maybe we are going to need rewriting whole class. Java provides a more flexible mechanism, interfaces. Let’s modify the previous class for using interface:



Instead of having a class with fixed functionality, we just declare an abstract class with a method but no functionality inside. Functionality is defined almost at calling time. Then, the same Add method can be used for a simple or a deeper functionality. Even, the Add method can be used for performing a subtraction operation, but that is cannot be a good idea. Something important, this flexibility comes at a cost, more lines of code. And as we want flexibility without his payoff, Lambda expressions can help us. Let’s take a look at the following code:


The three options will get us the same result, but the last one has both, flexibility and less lines of code. How does it work? Using functional programming style, that is more like mathematical formulas than object oriented. Second and third options are using interfaces (abstract classes) which functionality is resolved almost at calling time. But the later include the “@FunctionalInterface” directive that allows this interface within functional programming, using Lambda expressions. Our new code starts with a compact instantiation of the interface, followed by equal sign (“=”) and the Lambda expression.

Lambda expression has the following basic syntax:

( Parameter 1, …, Parameter n ) -> { method body }

We can read this syntax as something like “with these parameters, do these actions”. The first thing we note on the third code is that it has the less lines of code. Second. If you manage math notations, syntax is more readable, less verbose and, for some points of view, more elegant.

Maybe, the main disadvantage is that Lambda expressions can only be used with functional interfaces, ad not other “more object oriented” classes. Other con, but not for all, is that it can seem some confused for programmers used to model everything in an object-oriented style.

Anyway, it is a good tool that we can used when appropriate. Try these examples and later, when you write other programs, evaluate and test how looks and works the code using Lambda expressions. Good luck!