Skip to content

L58 - Programación Funcional

La programación funcional es un paradigma de programación que trata la computación como la evaluación de funciones matemáticas y evita el cambio de estado y los datos mutables. No es un concepto nuevo, pero ha ganado gran popularidad en JavaScript moderno.

Una función pura cumple dos condiciones:

  • Misma entrada → misma salida (determinismo).
  • Sin efectos secundarios (no modifica variables externas, no escribe en consola/archivos/DB).
// ❌ Impura: modifica una variable externa
let total = 0;
function agregarImpuro(valor) {
total += valor;
return total;
}
// ✅ Pura: no modifica nada externo
function agregarPuro(total, valor) {
return total + valor;
}
// ❌ Impura: tiene efecto secundario (console.log)
function doble(x) {
console.log(`Calculando doble de ${x}`);
return x * 2;
}
// ✅ Pura
function doblePuro(x) {
return x * 2;
}

Los datos no se modifican: se crean nuevos datos a partir de los originales.

// ❌ Mutación
const usuario = { nombre: 'Ana', edad: 25 };
usuario.edad = 26; // ❌ Mutamos el objeto original
// ✅ Inmutabilidad
const usuarioActualizado = { ...usuario, edad: 26 };
// usuario original no cambia
// ❌ Mutación en arrays
const frutas = ['manzana', 'pera'];
frutas.push('uva'); // ❌
// ✅ Inmutabilidad
const nuevasFrutas = [...frutas, 'uva'];
// o
const nuevasFrutas2 = frutas.concat('uva');

3. Funciones de orden superior (Higher-Order Functions)

Section titled “3. Funciones de orden superior (Higher-Order Functions)”

Son funciones que reciben funciones como argumento o devuelven una función.

// Recibe una función
function operar(a, b, fn) {
return fn(a, b);
}
operar(5, 3, (x, y) => x + y); // 8
operar(5, 3, (x, y) => x * y); // 15
// Devuelve una función
function crearMultiplicador(factor) {
return function(numero) {
return numero * factor;
};
}
const duplicar = crearMultiplicador(2);
const triplicar = crearMultiplicador(3);
console.log(duplicar(5)); // 10
console.log(triplicar(5)); // 15
const numeros = [1, 2, 3, 4, 5];
// map: transforma cada elemento
const cuadrados = numeros.map(n => n ** 2); // [1, 4, 9, 16, 25]
// filter: selecciona elementos
const pares = numeros.filter(n => n % 2 === 0); // [2, 4]
// reduce: acumula
const suma = numeros.reduce((acc, n) => acc + n, 0); // 15
// find: primer elemento que cumple
const mayorQue3 = numeros.find(n => n > 3); // 4
// some / every
const algunPar = numeros.some(n => n % 2 === 0); // true
const todosPares = numeros.every(n => n % 2 === 0); // false

En lugar de heredar (POO), en programación funcional se componen funciones pequeñas:

const aMayusculas = str => str.toUpperCase();
const quitarEspacios = str => str.trim();
const agregarExclamacion = str => `${str}!`;
// Composición manual
const resultado = agregarExclamacion(aMayusculas(quitarEspacios(' hola ')));
console.log(resultado); // 'HOLA!'
// Composición con helper
function componer(...fns) {
return function(valorInicial) {
return fns.reduceRight((valor, fn) => fn(valor), valorInicial);
};
}
const transformar = componer(agregarExclamacion, aMayusculas, quitarEspacios);
console.log(transformar(' hola ')); // 'HOLA!'
Programación FuncionalPOO (Herencia)
Compone funciones pequeñasHereda de clases padre
Datos inmutablesEstado mutable
Sin efectos secundariosLos métodos pueden mutar
Más predecible y testeablePuede crear jerarquías rígidas
Evita el this problemáticothis es central
  1. Mutar argumentos: modificar arrays/objetos que recibes como parámetro.
  2. Mezclar paradigmas sin cuidado: no pasa nada, pero sé consciente de cuándo mutas.
  3. Olvidar el return implícito: en arrow functions de una línea es opcional, pero en cuerpos con llaves es obligatorio.
  4. No usar ... para copiar objetos/arrays profundos: ... hace copia superficial (shallow copy).
// Copia superficial vs profunda
const original = { a: 1, b: { c: 2 } };
const copiaSuperficial = { ...original };
copiaSuperficial.b.c = 99; // ❌ Modifica original también
// Deep clone (una opción)
const copiaProfunda = JSON.parse(JSON.stringify(original));

🎯 Regla de oro: prefiere funciones puras e inmutabilidad. Tu código será más predecible, testeable y fácil de depurar.