Functional programming and Object Oriented paradigm
After reading through almost all the content across the web, and not finding any practical examples with a blend of theoretical concepts, I just sat calm for an hour doing nothing but just thinking about why and where I would use FP.
I got a chance to work on clojure for a couple of months. I still remember going back to my manager and telling him about the shitty work which I had.
A year down the line, and lucky enough to meet a person in one of the FP interviews, I realized the whole new world of FP. I was not able to clear the interview, but the interview experience was better than most of the product based companies I had interviewed with.
So after sitting for an hour this is what I came up with — hope this helps!
Functional paradigm is used where we need concurrency. How are you going to take advantage of every computer core available to you? Embrace the functional paradigm!
The main underlying concept in FP programming is immutable data and concurrent architectures.
Concurrency and multithreading ?
Concurrency is running multiple tasks at the same time. Multi-threading is a way of programming where multiple tasks looks like working at the same time, but it is actually time driven and controlled by the OS.
Multithreading makes a system faster, concurrency with multithreading makes it even faster.
Difference between mutable and immutable ?
FP creates immutable data rather than languages like Java, Python which works on Mutable data.
Immutable — Once you create the data, the data can’t be changed. Whenever you perform any operation it will create new memory locations and new variables to store the value. The Data Structure is a persistent data structure that always preserves the previous version of itself when it is modified.
Mutable — Any variable that you encounter in OOPs paradigm is a mutable data which can be changed.
We can consider a very basic Java example here of String and StringBuffer :
String class is immutable and StringBuffer class is mutable.
String val = “vvk”;
val+”singh”;System.out.println(val); // outputs vvk — immutabilityStringBuffer valB = new StringBuffer(“vvk”);valB.append(“singh”);System.out.println(valB); // outputs vvksingh — mutabiliity
Concurrency in FP
In concurrent architectures, FP will be faster as all the operations are independent of data and methods are the building block of FP unlike OOPs where objects play the vital role.
As the data is immutable in FP, we can perform different tasks parallely without the fear of deadlock and without being extra cautious while writing programs. In OOPs, whenever we want to implement multithreading , we need to synchronize code blocks or methods so that there is no race condition between two operations working on the same object at a given time. This is where FP wins the battle, because the functions defined here are pure functions and data is immutable meaning we can parallelly do multiple tasks.
Example :
Consider you want to perform some basic mathematical operations on a number.
In FP :
a,b are passed as parameters
add(a,b).subtract(a).divide(a) //Consider these are predefined functions in any FP
In OOP:
class Test { public void calculate(a,b) { int c = add(a,b) int d = subtract(c,a) int f = divide(d,a) print(f) }}
IN OOPs, if you see, there is a need to store the data into different variables, which are then passed to methods.
In concurrent architecture you will create an object for the class Test (assume test), and call the above method on that object
test.calculate(a,b)
If this is called parallely multiple times test.calculate(a,b) using threading , then there is a possibility of c,d,f variables going out of sync and giving unexpected output or thread error.
While if you call the FP logic above multiple times, there wouldn’t be any discrepancy in the output because the functions used are pure and data is immutable, data doesn’t share state with different context.
How to effectively maintain immutability ?
Generally people argue that creating new objects for every operation is time consuming in FP, which makes it slower. However languages Clojure have their own implementation of managing data structures and its operations.
Example :
Consider you have two linked list :
L1 = 1 -> 2 → 3
L2 = 4 -> 5 -> 6
In FP, you need to perform an operation of merging the linked list with output :
1 -> 2 -> 3 -> 4 -> 5 -> 6
What is actually done in FP is a new memory block is created for 1 -> 2 -> 3 and then 3 points to the memory address of L2.
Screenshot attached for easy understanding :
I found this article to be great; in case you need more idea on FP :
https://freecontent.manning.com/the-foundations-of-functional-concurrency/
Languages like Java have come with different approaches and implementations to counter for the usability of concurrency. Still in the long run for relatively larger applications, it is hard to manage and prone to errors. A combination of object-oriented programming with the benefits of functional programming can go a long way.
The simplest way to avoid problems with concurrency is to share only immutable data between threads.
Example of FP in java :
Create a list of integers in java
List<Integer> list = Arrays.asList(1,2,3,4,5)
list.stream().map(number -> number*2).forEach(System.out::println); // prints 1,4,6,8,10System.out.println(list) // prints 1,2,3,4,5
Some references :
https://blog.cleancoder.com/uncle-bob/2014/11/24/FPvsOO.html
Conclusion :
The bottom line here is simply this. OO programming is good, when you know what it is. Functional programming is good when you know what it is. The choice of a paradigm depends completely on your business use case.