Rio: Hello Mr Archie, I have a question for you. I am not able to understand actually what is functional programming? I have always been reading about that while using functional programming we need to forget everything we know about programming. How can we forget about the variable, values, functions, datatypes, indentation, name spaces, hashes, collections, classes, inheritance etc. This statement is quite confusing. Could you please help me understand about the actual idea behind functional programming?
Mr Archie: Hey Rio, that indeed is a very good question. I would try to explain in an easy manner. The above statement should actually be corrected. The functional programming is all about refactoring everything you know about programming.
- There are no side effects on the function being called, which means there should be no change in the state of input variables. This can be achieved e.g by using immutable input parameters. e.g say if an x = {3, 4, 5} is applied over a function y which is f(x), at the end of evaluation of y the value of x should still remain {3, 4, 5}. Now a question will arise in your mind that what if the parameters passed are something like array of hash-maps which are mutable. For this we actually always need to make sure that such data structures are immutable. Another question will now come into your mind that if everything is immutable how can we apply logic what needs to be performed. For this, we have to make sure that our data structure should be having an operation to return create a copy of itself which are mutable. To limit the number of copies while creating required mutable data structure, efficient persistent data structures were introduced. These are actually mutable and support copy on modification operation.
- There are final desired effects produced as per the requirement of the application (enduser). That means we need to implement mutable state now into the application. This can be done by using bridges between the above function with (no side effect) on one side and the business logic on the other which will give the desired result. The function is thrown at the bridge which performs the desired logic. Examples of such bridges are Atomic classes, messaging queues etc which perform the task of producing desired final results.
- There are no assignments statements in functional programs, so the variables are immutable
- We don't need to worry much about multithreading as the input data is immutable.
- Since there are no side effects, so there is very less chance of introducing bugs.
- Since the functions are referentially transparent, which means independent of each other, so the order of the program statements need not to be imperative.
- Using Anonymous inner classes where we can create and instantiate a class at the same time. This is used if we want to use class declaration just once.
- Using Lambda Expression or anonymous functions which can accept parameters and return a value.
- Using Method References.
- Referring static method
public class MethodReferenceForStaticMethods {
public static void main(String[] args) {
List<String> list = List.of("rio", "mr. achie");
list.stream().forEach(word -> {
StringUtils.toRootUpperCase(word);
});
}
}The same result can also be achieved using method references as below
public class MethodReferenceForStaticMethods {
public static void main(String[] args) {
List<String> list = List.of("rio", "mr. achie");
list.forEach(StringUtils::toRootUpperCase);
}
}
- Referring instance method
public class MethodReferenceForInstanceMethods {
public static void main(String[] args) {
MethodReferenceForInstanceMethods instance =
new MethodReferenceForInstanceMethods();
MyFunctionalInterface methodReferenceForInstanceMethods =
instance::instanceMethod;
methodReferenceForInstanceMethods.say("a", "b", 5, 8);
}
public void instanceMethod(
String a, String b, int c, Object d
) {
System.out.println("Hello, this is non-static method by: "
+ a + " " + b + " " + c + " " + d);
}
interface MyFunctionalInterface {
void say(String a, String b, int d, Object e);
}
}