Lately, I have been reading lots of papers talking about Functional Programming (FP), then I decided to summarize what I have learned writing this article.
Before throwing a bunch of concepts here, do you know what is functional programming? It is a software development paradigm that is becoming more and more well-known among developers. The idea is coding simply and cleanly avoiding side effects using the power of functions.
Wikipedia defines Functional Programming as
… a programming paradigm — a style of building the structure and elements of computer programs — that treats computation as the evaluation of mathematical functions and avoids changing state and mutable data — Wikipedia
Most of the papers I have read address the following subjects.
- Pure Functions;
- Immutability;
- Referential Transparency;
- Functions as first-class entities;
- Higher-Order Functions (HOF);
I believe it is important to understand the concepts mentioned before because you might be using FP and you do not even know. To comprehend them is essential to improve the quality of your code. So, let’s go to the concepts.
Pure Functions
You might be asking yourself what are pure functions? how do you create or to determine whether a function is pure or not?
Pure functions always return the same results when given the same inputs. Consequently, they have no side effects. Pure functions allow referential transparency, which means you can replace a function call with its resulting value. — Cody Arsenault
Well, based on the reference above we can define a pure function as something deterministic. I have written a simple example below.
Could we consider it a pure function? We cannot consider it one example of pure function due to the global variable used and not passed as a parameter. However, we can fix it by passing the global variable as a parameter, but I rather write it as below.
Some examples of impure functions are the ones that read external files, generate random numbers. It is due to the output that may be different even calling these functions passing the same parameters.
// It generates a value given a minimum and a maximum value
function getRandomArbitrary(min, max) {
return Math.random() * (max - min) + min;
}
getRandomArbitrary(1, 10);
getRandomArbitrary(1, 10);
With that being said we can conclude that using pure functions concept the code becomes easier to test and we do not need to mock anything.
- Given a parameter w → expect the function to return value x
- Given a parameter y → expect the function to return value z
Immutability
The ability to remain the same over time under all circumstances
Data is immutable when its state cannot change after its creation. You cannot change an immutable object. You must create a new object with the new value instead. The following example is a common situation where people could refactor their code to follow the immutability principles.
Recursion is a great way to avoid mutability in iterations. Rewriting the code above we could have something like below.
The sum function receives the product array and calls itself until we get an empty array. For each iteration, we will add the product price to the total. In the end, we have the summation of prices and also immutable variables.
Referential Transparency
Referential transparency is the concept of having the same output, whenever we use the same input. For example, having the following pure function.
const cube = (number) => number * number * number;
Calling it three times passing the number four we always will get 64 as the result. So, we could replace cube(4) with 64. Therefore, we could affirm that referential transparency is the result of writing a pure function that has immutable data.
Functions as first-class entities
The idea behind functions as first-class entities is that we should be treating a function as a value and using it as data. When we adopt this point of view we can start to refer to it from constants and variables, also pass it as a parameter to other functions and even return it as a result of other functions. Getting back to our recursion example, we could have two new functions, totalAfterTaxes and applyDiscount5.
As you can see we are consuming functions as an argument. We are creating a chain of execution that removes the necessity of creating variables to store the results to pass into the other functions.
Higher-Order Functions (HOF)
The definition of a higher-order function is a function that either takes one or more functions as arguments or returns a function as its result.
Those new functions implemented above are an example of higher-order functions. If you are familiar with JavaScript you may have heard about filter and map functions. They are a common example of higher-order functions. Let’s take a look at some examples.
Filter
Let’s suppose we want all products under $2. We can use the filter function to evaluate another function and if the result is true store item into a new array.
Map
The map method can transform a collection by applying a function to all its elements and build a new collection from the returned values. If we would like to double the price of those products we could do something like the example below.
My conclusion
After reading many papers and writing this article I think the Functional Programming (FP) paradigm a great way to coding high testable and bug-free applications. I hope to pass to you a little bit about my understanding of FP.
Note: This was my first article in English, so I am sorry for any grammatical error 😅
Top comments (0)