DEV Community

Cover image for Understanding concepts of functional programming with JavaScript
Helder Burato Berto
Helder Burato Berto

Posted on • Edited on • Originally published at helderburato.com

Understanding concepts of functional programming with JavaScript

Originally posted on [helderburato](https://helderburato.com/understanding-concepts-of-functional-programming-with-javascript/)

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"],
  }
];
Enter fullscreen mode Exit fullscreen mode

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

Photo by Ricardo Gomez Angel

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" ]}]
Enter fullscreen mode Exit fullscreen mode

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" ]}]
Enter fullscreen mode Exit fullscreen mode

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" ]}]
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

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!

References

Top comments (7)

Collapse
 
mbackermann profile image
Mauricio Ackermann

From mutability example, the code is wrong. If you console.log(animals) it will always print 2, since it has never been changed

Collapse
 
helderberto profile image
Helder Burato Berto • Edited

Thanks for the reply! I updated the variable to mutatedAnimals should print the correct length.

Collapse
 
mbackermann profile image
Mauricio Ackermann

Np! Nice article btw! Thank you for your contribution.

Collapse
 
karranb profile image
Karran Besen

Awesome post

Collapse
 
helderberto profile image
Helder Burato Berto

Thanks! 😁

Collapse
 
dfelczak profile image
Dominik Felczak • Edited

Nice and well explained but this is obviously just a tip of the iceberg.

Collapse
 
helderberto profile image
Helder Burato Berto

True story! I'm thinking to create new posts talking about more deeper level of functional programming.