This content originally appeared on Level Up Coding - Medium and was authored by Sohee Kim
Super Java — Functional Programming in Object-Oriented Programming(1/2)
Please read my previous post before you continue reading.
In my previous post, I showed how using Functional Interface and Lambda Expression adds syntactic sugar to the code. It’s a good enough reason why we should consider using those. However, is that all they offer? There must be more reasons why Java introduced these concepts.
To get straight to the answer, Functional Interface and Lambda Expression allow us to adopt Functional Programming in Java. Wait a minute. Wasn’t Java an Object-Oriented programming language? What is Functional programming in the first place and why do we have to adopt Functional Programming in Java?
In this post, I will start by going over what Object-Oriented Programming language is and explore the motivation behind adopting Functional Programming in Java. Then, I will outline some of the key concepts of Functional Programming.
I. Why use functional programming in Java
Java is an Object-Oriented Programming language. What does Object-Oriented Programming (OOP) mean anyway? You probably know that OOP is a way of programming where we define objects with attributes, assign data, and use methods to manipulate the data. You probably are also familiar with the OOP concepts: encapsulation, abstraction, polymorphism, and inheritance. Let’s recap.
- Encapsulation is data hiding. You hide the variable from other classes, and you only provide the methods to access the variables.
- Abstraction is hiding logic. Think about how an interface work. You don’t need to know how it does but what it can do.
- Polymorphism is the ability to take many forms. It allows performing the same action in different ways usually achieved by inheritance.
- Inheritance is extending a class. The subclass which extends the superclass inherits the superclass’s public and private methods and variable.
If we think about why we came up with these concepts, we can understand OOP better. Since data in Java objects are mutable, it is prone to side effects and unwanted changes. This is why we use encapsulation and abstraction to control who can view and edit the data. Since the building block for OOP is an object, we often end up with extensive boilerplate codes to create every single object. This is why we use polymorphism and inheritance to achieve code reusability and extensibility.
What if there is another way to tackle some of the underlying issues in OOP regarding mutable state and long boilerplate code? This is where Functional Programming comes into play.
Introducing Functional Programming
Functional Programming (FP) is a style of programming computation as math functions. FP has no state nor mutable variables. How is this possible? It’s similar to using all variables with the final keyword. Initially, FP has not received much attention because FP used a lot of memory to be stateless and memory was very expensive. However, memory is no longer expensive. More ironically, this particular trait has made FP more appealing. As modern software programs get more and more complex, the demand for asynchronous multi-core programming has increased. Since FP has no state, there’s no blocking or concurrency issue which works like a charm in multi-core programming settings.
FP removes moving parts and optimizes operation for concise and error-free code. Wouldn’t adopting this particular way of coding (no state and no mutable variables) in OOP make code more effective and efficient?
II. How Functional Programming works
To use Functional Programming in Java, let’s dive into the fundamentals of functional programming. The two key concepts of FP are first-class functions and pure functions.
First-class functions
First-class functions mean that functions are treated as first-class citizens. First-class citizens support all operations such as being assigned to a variable, passed to a parameter, and returned as a value. This property enables higher-order functions. Higher-order functions are functions that receive a function as an argument and return a function. In FP, higher-order functions are used for function composition and currying.
Pure Functions
A function is a pure function when the execution has no side effect and the return value only depends on the input.
A function has a side effect when it changes a state outside of the function. If the execution of a function changes the member variable of a class or an object or even an external system such as databases, the function has a side effect.
Let’s look at some examples.
public class Tiger {
public String cry (String sound) {
return "Tiger cries" + sound;
}
}
cry has no side effects because it doesn’t change the state outside of a function. The return value only depends on the input sound.
However, cry2 below has side effects.
public class Tiger {
String tigerCry = "Tiger cries ";
public String cry2 (String sound) {
tigerCry += sound;
return tigerCry;
}
}
When we execute tiger.cry2(“roar”), it updates the member variable tigerCry to “Tiger cries roar.” This violates the pure function’s trait to not change the state outside of the function.
Tiger tiger = new Tiger();
System.out.println(tiger.cry("roar"));
Also since the value of tigerCry is changed, the execution of the code below returns “Tiger cries roar howl.” Here, the output not only depends on the input but also on the member variable, tigerCry. This goes against the pure function’s trait where return value should only depend on the input
System.out.println(tiger.cry("howl"));
To clarify, the methods can have local variables, to temporally store its state, It just can’t reference any member variables of the class or the objects.
III. Lambda Expression and Functional Programming
Lambda Expression and functional interface in Java is introduced so that functional programming can be more easily adopted in Java. Using Lambda expression, we can mimic the functional programming syntax of assigning a method to a variable or passing it to a parameter. It almost seems like we are treating functions as first-class citizens. However, technically speaking, lambda expression still implements a functional interface. Thus, it is an object, not a function.
Before I end this post, I want to share a quote that capsulizes OOP and FP.
OO makes code understandable by encapsulating moving parts.
FP makes code understandable by minimizing moving parts.
— Michael Feathers
In my next post, I’ll provide examples using Lambda Expression and functional interfaces to apply functional programming concepts in Java.
Super Java — Functional Programming in Object Oriented Programming was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Sohee Kim
Sohee Kim | Sciencx (2021-02-12T15:22:22+00:00) Super Java — Functional Programming in Object Oriented Programming. Retrieved from https://www.scien.cx/2021/02/12/super-java%e2%80%8a-%e2%80%8afunctional-programming-in-object-oriented-programming/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.