Chapter 17: Functional Programming
Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids changing state and mutable data. This chapter introduces key concepts in functional programming, including pure functions, immutability, and functional composition.
Pure Functions
Definition
A pure function is a function that:
- Always produces the same output for the same input.
- Does not cause any side effects, meaning it does not modify any external state or variables.
Characteristics
- Deterministic: Given the same input, a pure function will always return the same output.
- No Side Effects: It does not alter any state outside its scope or rely on external state.
Example
// Pure Function
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // Output: 5
console.log(add(2, 3)); // Output: 5 (same output for same input)
In this example, add is a pure function because it always returns the same result for the same inputs and does not modify any external state.
Immutability
Definition
Immutability refers to the concept where data cannot be changed once it has been created. Instead of modifying data, you create new data structures.
Benefits
- Predictable Code: Immutable data structures lead to more predictable code since data does not change unexpectedly.
- Easier Debugging: Changes to data do not affect other parts of the program, making it easier to trace and debug issues.
Example
// Mutable Example
let array = [1, 2, 3];
array.push(4); // Modifies the original array
console.log(array); // Output: [1, 2, 3, 4]
// Immutable Example
const array = [1, 2, 3];
const newArray = [...array, 4]; // Creates a new array
console.log(newArray); // Output: [1, 2, 3, 4]
console.log(array); // Output: [1, 2, 3] (original array is unchanged)
In the immutable example, newArray is created by copying the original array and adding an element to it, while the original array remains unchanged.
Functional Composition
Definition
Functional composition involves combining two or more functions to create a new function. The output of one function becomes the input of the next.
Syntax
In JavaScript, functional composition can be done manually or with libraries. Here is a manual approach:
// Function to compose
const add = (x) => x + 1;
const double = (x) => x * 2;
// Compose function
const addThenDouble = (x) => double(add(x));
console.log(addThenDouble(3)); // Output: 8 (add(3) => 4, double(4) => 8)
Using Composition Libraries
Libraries such as Lodash provide utilities for functional composition.
// Lodash example
const _ = require("lodash");
const add = (x) => x + 1;
const double = (x) => x * 2;
const addThenDouble = _.flow([add, double]);
console.log(addThenDouble(3)); // Output: 8
In this example, _.flow from Lodash is used to create a composed function that applies add and then double in sequence.
Summary
In this chapter, we explored the core concepts of functional programming:
- Pure Functions: Functions that always return the same output for the same input and do not cause side effects.
- Immutability: The practice of not modifying existing data but instead creating new data structures.
- Functional Composition: Combining functions to create new functions where the output of one function is passed as input to another.
Adopting functional programming principles can lead to more predictable, maintainable, and bug-resistant code.