Let's understand the fundamental concepts of functional programming using JavaScript language.
The abbreviation FP will be used within this article to reference functional programming
.
Object Example
In this article we'll use the following object in our practical examples like the following:
const animals = [
{
"name": "Max",
"species" : "dog",
"likes": ["bones", "carrots"],
},
{
"name": "Teodore",
"species" : "cat",
"likes": ["mice", "carrots"],
}
];
What is functional programming?
FP is the basis in Lambda Calculus - a formal system developed in the 1930s. Lambda Calculus is a mathematical abstraction that you could read more on Lambda calculus definition - Wikipedia.
The FP programming paradigm is focused on writing more functions and make function compositions.
Composition
Function composition is a way to combine multiple functions to build one result.
In mathematical we write like f(g(x))
when receiving the results from g(x)
will be passed to the upper scope called f
.
See the following example:
const isDog = animals => animals.filter(animal => animal.species === 'dog');
const isCat = animals => animals.filter(animal => animal.species === 'cat');
const likeCarrots = animals => animals.filter(animal => animal.likes.find(like => like.includes('carrots')));
console.log(likeCarrots(isDog(animals)));
// => [{ name: "Max", species: "dog", likes: ["bones", "carrots" ]}]
console.log(likeCarrots(isCat(animals)));
// => [{ name: "Teodore", species: "cat", likes: ["mice", "carrots" ]}]
Automate the Composition process
Let's create an automation to previous example:
const compose = (...fns) => x => fns.reduceRight((v, fn) => fn(v), x);
console.log(compose(isDog, likeCarrots)(animals));
// => [{ name: "Max", species: "dog", likes: ["bones", "carrots" ]}]
console.log(compose(isCat, likeCarrots)(animals));
// => [{ name: "Teodore", species: "cat", likes: ["mice", "carrots" ]}]
The method called compose
will execute all functions from right to left using reduceRight
.
Note: we've got the same results with a much more readable and cleaner code.
Normally, when want to execute sequentially, so we use the pipe
method like the following example:
const pipe = (...fns) => x => fns.reduce((v, fn) => fn(v), x);
console.log(pipe(isDog, likeCarrots)(animals));
// => [{ name: "Max", species: "dog", likes: ["bones", "carrots" ]}]
console.log(pipe(isCat, likeCarrots)(animals));
// => [{ name: "Teodore", species: "cat", likes: ["mice", "carrots" ]}]
Note: we've got the same results from the composed method because we just filtered the results, however, in cases you want to print different value, with is a nice approach.
I recommend the article A quick introduction to pipe() and compose() in JavaScript where you may understand the concepts of pipe and compose better.
Immutability
In immutability, we consider elements that won't mutate itself when we add a new property or change.
See an example when I've added new animal and create a new instance from animals
:
const tildorCat = { name: "Tildor", species: "cat", likes: ["mice", "carrots" ]}
const mutatedAnimals = [...animals, tildorCat];
console.log(animals.length); // => 2
console.log(mutatedAnimals.length); // => 3
We've used the base animals
to create a new instance with the new animal instance.
Keep in mind when talking about immutability the initial values won't change, instead, it creates a modified instance.
Pure Functions
Pure functions are used to avoid side-effects
so guarantee when you pass an input it will always return the same output.
You can read more about What is a Pure Function? - DEV Community 👩💻👨💻.
Wrapping Up
That's all folks! I tried to show some fundamentals concepts and my personal opinion about some use cases of FP, I hope it helps you.
Feel free to comment below if you have any questions, I'll be happy to help you.
Enjoy programming!
Top comments (7)
From mutability example, the code is wrong. If you console.log(animals) it will always print 2, since it has never been changed
Thanks for the reply! I updated the variable to
mutatedAnimals
should print the correct length.Np! Nice article btw! Thank you for your contribution.
Awesome post
Thanks! 😁
Nice and well explained but this is obviously just a tip of the iceberg.
True story! I'm thinking to create new posts talking about more deeper level of functional programming.