// PURE FUNCTIONS
// Pure - same input, same output, no side effects
function add(a, b) {
return a + b;
}
console.log(add(2, 3)); // Always 5
console.log(add(2, 3)); // Always 5
// Pure - doesn't modify input
function doubleArray(arr) {
return arr.map(n => n * 2);
}
const numbers = [1, 2, 3];
const doubled = doubleArray(numbers);
console.log(numbers); // [1, 2, 3] (unchanged)
console.log(doubled); // [2, 4, 6]
// Pure - string manipulation
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
}
console.log(capitalize('hello')); // 'Hello'
console.log(capitalize('hello')); // 'Hello' (same)
// Pure - object transformation
function updateUser(user, updates) {
return { ...user, ...updates }; // New object
}
const user = { name: 'John', age: 30 };
const updated = updateUser(user, { age: 31 });
console.log(user.age); // 30 (unchanged)
console.log(updated.age); // 31
// IMPURE FUNCTIONS
// Impure - modifies external variable
let total = 0;
function addToTotal(value) {
total += value; // Side effect!
return total;
}
console.log(addToTotal(5)); // 5
console.log(addToTotal(5)); // 10 (different!)
// Impure - mutates argument
function addItemImpure(arr, item) {
arr.push(item); // Mutates input!
return arr;
}
// Impure - I/O operation
function logValue(value) {
console.log(value); // Side effect!
return value;
}
// Impure - uses external state
let multiplier = 2;
function multiplyByMultiplier(n) {
return n * multiplier; // Depends on external variable
}
console.log(multiplyByMultiplier(5)); // 10
multiplier = 3;
console.log(multiplyByMultiplier(5)); // 15 (different!)
// Impure - random output
function getRandomNumber() {
return Math.random(); // Non-deterministic
}
// Impure - current time
function getCurrentTimestamp() {
return Date.now(); // Different each call
}
// CONVERTING IMPURE TO PURE
// Impure version
function discountPriceImpure(price) {
const discount = 0.1; // Hard-coded
console.log('Calculating discount'); // Side effect
return price - (price * discount);
}
// Pure version
function discountPricePure(price, discount) {
return price - (price * discount);
}
// Separate side effects
function calculateAndLog(price, discount) {
const result = discountPricePure(price, discount); // Pure
console.log('Result:', result); // Impure, but isolated
return result;
}
// REAL-WORLD EXAMPLES
// Pure - shopping cart total
function calculateTotal(items) {
return items.reduce((sum, item) => {
return sum + (item.price * item.quantity);
}, 0);
}
const cart = [
{ name: 'Book', price: 10, quantity: 2 },
{ name: 'Pen', price: 2, quantity: 5 }
];
console.log(calculateTotal(cart)); // 30
// Pure - filtering and mapping
function getActiveUserNames(users) {
return users
.filter(user => user.active)
.map(user => user.name);
}
// Pure - form validation
function validateEmail(email) {
return email.includes('@') && email.includes('.');
}
function validatePassword(password) {
return password.length >= 8;
}
function validateForm(data) {
return {
emailValid: validateEmail(data.email),
passwordValid: validatePassword(data.password)
};
}
// BENEFITS DEMONSTRATION
// 1. Easy testing
function multiply(a, b) {
return a * b;
}
// Simple test
console.assert(multiply(2, 3) === 6);
console.assert(multiply(2, 3) === 6); // Always same!
// 2. Memoization (caching)
function memoize(fn) {
const cache = {};
return function(...args) {
const key = JSON.stringify(args);
if (key in cache) {
console.log('From cache');
return cache[key];
}
const result = fn(...args);
cache[key] = result;
return result;
};
}
// Only works reliably with pure functions
const memoizedMultiply = memoize(multiply);
console.log(memoizedMultiply(5, 6)); // Computes
console.log(memoizedMultiply(5, 6)); // From cache
// 3. Parallelization (conceptual)
const data = [1, 2, 3, 4, 5, 6, 7, 8];
// Safe to parallelize because pure
const doubled = data.map(n => n * 2);
// BEST PRACTICES
// Do: Keep business logic pure
function calculateDiscount(price, percentage) {
return price * (percentage / 100);
}
// Do: Separate I/O from logic
function processOrder(order) {
const total = calculateTotal(order.items); // Pure
saveToDatabase(total); // Impure, but separated
return total;
}
// Don't: Mix concerns
function badCalculate(price) {
console.log('Calculating...'); // Impure!
const result = price * 0.9;
saveToDatabase(result); // Impure!
return result;
}