Functional programming is an important, yet overlooked, concept in software development. In a world dominated by object oriented programming (OOP) and separation of concerns, most developers completely overlook the functional programming paradigm when looking for jobs or learning new technologies. In this article, we discuss the basics of what functional programming is and the benefits of practicing it when writing code.
Functional programming is a paradigm for writing code. In other words, functional programming is not what you write your code with but HOW you write your code. It is a way of approaching development challenges.
Object oriented programming is also considered a paradigm. When you organize your code into classes with inheritance, data types, and methods you are really just adhering to the OOP paradigm.
If both OOP and functional programming are just paradigms, then what makes them different? There are a few basic concepts that distinguish functional programming from other paradigms. They are:
Let's discuss each one of these topics and how they apply to functional programming:
Functional programming relies heavily on pure functions. A function is considered pure if it always returns the same output for a given input and has no side effects. Side effects can be anything from printing a message to the console or calling another function from within the parent function. Take the following as an example:
return x * 2;
This function is considered impure because of the side effects. While the function will always return x * 2 it's also updating some User object and printing a message to the console. These side effects make the function impure because we can't guarantee the same thing will happen every time. What if the User.save() method silently fails or we forget we are logging messages to the console?
Now let's take a look at a pure function:
return x * 2;
This is considered a pure function since it will ALWAYS return the same result based on the parameters we give it.
Why is this important? Functional programming revolves around independent functions feeding other functions. The result of one function is used as the parameters of another function (f(a(x))). When functions are pure, we can safely use them within other functions. Their return values are reliable and independent of other functions. This results in more reliable code.
In object oriented programming, you have classes with private/public methods. They can communicate with other classes, share data, etc. When objects rely on one another like this they have a shared state.
Shared state can be a problem for several reasons. When things don't occur in the right order or different functions finish running at different times you can run into issues. Functional programming avoids the idea of shared state. Everything is self contained inside functions. Replacing functions with their resulting values will not alter or effect different parts of the program.
Functional programming encourages immutable data types. An immutable object is one that can't be changed after creation. This ensures consistency with data flow and prevents unpredictable things from happening.
Functional programming falls within the declarative paradigm. This essentially means the code you write tells your program WHAT to do vs HOW to do it. For instance, a for loop is an imperative statement because it explains what to do FOR each item in a data set, whereas something like getData(getUser())is more declarative in that it doesn't describe how to get the user and simply calls another function.