Functional programming has gained traction in modern development due to its ability to produce more predictable, modular, and testable code. In this post, we explore four fundamental principles: immutability, function composition, pure functions, and arrow functions.
๐ง Immutability: Protect Your State
Immutability means that once a value is created, it cannot be changed. Instead of mutating data, we return new versions with the desired updates.
โ Why is it useful?
- Prevents unpredictable side effects
- Easier debugging and testing
- Ideal for concurrent environments (like React or Redux)
โ Mutable example:
const user = { name: 'Alice', age: 25 };
user.age = 26; // Mutation
โ
Immutable example:
const user = { name: 'Alice', age: 25 };
const updatedUser = { ...user, age: 26 }; // New copy with changes
๐ Function Composition: Chain Your Logic
Function composition means combining small, reusable functions to build more complex logic.
const trim = str => str.trim();
const toUpper = str => str.toUpperCase();
const cleanAndCapitalize = str => toUpper(trim(str));
cleanAndCapitalize(" hello "); // "HELLO"
Or dynamically compose using a helper:
const compose = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);
const cleanAndCapitalize = compose(trim, toUpper);
๐ Benefit: cleaner, modular, and easily testable code.
๐ฆผ Pure Functions: No Surprises
A pure function follows two rules:
- Always returns the same output for the same inputs
- Has no side effects (doesn't modify external variables or interact with I/O)
โ
Pure function:
const add = (a, b) => a + b;
โ Impure function:
let counter = 0;
const increment = () => ++counter;
Advantages:
- Easier to test
- Fewer hidden dependencies
- Can be memoized or cached
๐ฝ Arrow Functions: Elegant and Contextual
Arrow functions (=>
) offer a concise way to declare functions in JavaScript and TypeScript. They also donโt have their own this
, making them perfect for callbacks.
โ
Simple example:
const double = n => n * 2;
๐ง Implicit return:
const sum = (a, b) => a + b;
๐ฏ this
behavior:
function Timer() {
this.seconds = 0;
setInterval(() => {
this.seconds++;
console.log(this.seconds);
}, 1000); // `this` works correctly
}
๐งน Conclusion
Adopting functional principles like immutability, composition, and pure functions (along with arrow functions) helps you write more declarative, maintainable, and robust code. These ideas are especially powerful in modern frameworks like React, NestJS, or Redux, where predictable data flow is crucial.
Top comments (0)