Exploring Functional Programming in JavaScript
Table of contents
Functional Programming is a programming paradigm that treats computation as an evaluation of mathematical functions and avoids state change and mutable data. In JavaScript, which is a multi-paradigm language, functional programming is becoming increasingly popular because it offers a way to create cleaner, more concise, and easier to understand code. Functional programming concepts will be explored and applied with JavaScript examples of use.
Roles as First Class Citizens
A central feature of functional programming is the treatment of functions as full citizens. In JavaScript, this means that functions can be assigned to variables, passed as arguments to other functions, and returned as values from other functions. This makes it possible to compose functions in a powerful and flexible way.
// Function assigned to a variable
const sum = function(a, b) {
return a + b
}
// Function passed as an argument
const execute = function(a ,b, operation) {
return operation(a,b)
}
console.log(execute(5,5,sum)) // Output: 10
Immutability and Immutable Data Structures
Data in functional programming is treated as immutable. That is, once data is created, it cannot be changed. In JavaScript, this can be done with immutable data structures or deep cloning. Libraries like Immutable.js or Lodash can be useful if you need to manipulate immutable data.
// Using Object.freeze to make an object immutable
const pet = Object.freeze({
name: 'Dog',
breed: 'Labrador'
});
// Attempt to modify an immutable object
pet.breed = 'Shih Tzu';
console.log(pet.breed); // Output: Labrador (not modified)
Higher Order Functions
Higher-order functions are functions that can accept other functions as arguments or return functions. They are a fundamental part of functional programming and enable powerful abstractions.
function multiplier(x) {
return function(y) {
return x * y
}
}
const execute = multiplier(3)
console.log(execute(6)) // Output: 18
Purity and Avoiding Side Effects
Pure functions are those that produce the same result given the same set of inputs and have no observable side effects. This makes the code more predictable and easier to test.
// Impure function
let counter = 0;
function increment() {
counter++;
return counter;
}
console.log(increment()); // Output: 1
console.log(increment()); // Output: 2
// Equivalent pure function
function incrementPure(counter) {
return counter + 1;
}
let newCounter = 0;
newCounter = incrementPure(newCounter);
console.log(newCounter); // Output: 1
newCounter = incrementPure(newCounter);
console.log(newCounter); // Output: 2
Function Composition
Function composition is a technique where multiple functions are combined to form a new function. This allows you to create modular and reusable code.
// Composition function
function compose(...functions) {
return function(intialVal) {
return functions.reduceRight((acc, func) => func(acc), intialVal);
};
}
// Usage example for the composition function
const sumAndMultiplier = compose(
x => x * 2,
x => x + 5
);
console.log(sumAndMultiplier(3)); // Output: 16 (5 + 3 = 8 * 2 = 16)
Conclusion
Functional programming propagates a powerful and distinct approach to software development. By the way, JavaScript, with its native support for functional programming, has proliferated, increasingly implementing its benefits by creating clean, modular code that is easy to understand and test. By using functional programming concepts and techniques, developers can produce complex routines and more sophisticated code and are therefore ready for the challenges faced by modern software development.
If you want to explore the topic in more depth, I recommend that you also read the article Understanding Functional Programming in JavaScript at once written by Matheus Lima