Paradigmas Fundamentales de Programación
Un paradigma de programación es un enfoque, modelo mental o estilo fundamental que guía la forma en que los programadores estructuran, razonan y escriben el código para resolver un problema.
No se trata de qué lenguaje de programación utilizamos, sino de cómo pensamos y organizamos las instrucciones y los datos. La mayoría de los lenguajes modernos son multiparadigma, lo que significa que permiten combinar diferentes enfoques según el caso de uso.
1. La Gran División: Imperativo frente a Declarativo #
1 PARADIGMAS DE PROGRAMACIÓN 2 │ 3 ┌───────────────────────┴───────────────────────┐ 4 ▼ ▼ 5 ENFOQUE IMPERATIVO ("CÓMO") ENFOQUE DECLARATIVO ("QUÉ") 6 (Instrucciones paso a paso y (Describe el resultado deseado 7 mutación de variables de estado) sin controlar el bucle manual) 8 ┌──────────┴──────────┐ ┌──────────┴──────────┐ 9 ▼ ▼ ▼ ▼ 10 PROCEDIMENTAL ORIENTADO A OBJETOS FUNCIONAL DECLARATIVO / SQL 11 (C, Pascal) (Java, C++, C#) (Haskell, Clojure) (SQL, HTML)
Python y JavaScript no encajan en una sola rama porque son lenguajes multiparadigma.
Los pondría atravesando varias categorías:
- Python → procedural + orientado a objetos + elementos de programación funcional.
- JavaScript → procedural + orientado a objetos + funcional.
2. Los Cuatro Paradigmas Principales #
Paradigma Imperativo y Procedimental #
- Filosofía: El programa es una secuencia cronológica de órdenes e instrucciones que cambian el estado de las variables en memoria paso a paso ("primero haz esto, luego evalúa aquello, después incrementa el contador").
- Conceptos clave: Bucles (
for,while), condicionales (if/else), funciones y procedimientos con variables mutables. - Lenguajes representativos: C, Pascal, Fortran, Go.
Paradigma Orientado a Objetos (POO) #
- Filosofía: El sistema se modela como un conjunto de objetos autónomos que colaboran entre sí enviándose mensajes. Cada objeto agrupa sus propios datos internos (estado) y las funciones que operan sobre ellos (comportamiento).
- Los Cuatro Pilares de la POO:
- Encapsulación: Ocultar el estado interno protegiendo los atributos privados.
- Abstracción: Exponer únicamente las operaciones esenciales mediante interfaces públicas.
- Herencia: Reutilizar y extender atributos y métodos de una clase base hacia clases hijas.
- Polimorfismo: Tratar diferentes objetos derivados bajo una interfaz común respondiendo con comportamientos específicos.
- Lenguajes representativos: Java, C++, C#, Smalltalk, Python.
Paradigma Funcional #
- Filosofía: El programa se concibe como una composición matemática de funciones puras. Se prohíbe la mutación de estado (Inmutabilidad) y los efectos secundarios imprevistos.
- Conceptos clave:
- Funciones de Primer Orden (First-Class Functions): Las funciones pueden guardarse en variables, pasarse como argumentos o retornarse desde otras funciones.
- Funciones Puras: Para las mismas entradas, la función siempre produce exactamente la misma salida sin alterar variables globales ni hacer I/O oculta.
- Transformación Declarativa: Uso intensivo de
map,filter,reducey recursividad en lugar de buclesforcon variables mutables.
- Lenguajes representativos: Haskell, Lisp, Elixir, Erlang, F#, JavaScript/TypeScript funcional.
Paradigma Declarativo y Basado en Reglas #
- Filosofía: Se especifica qué datos o resultado se desea obtener, delegando en el motor del sistema la optimización y la ejecución del algoritmo de búsqueda interno ("Qué queremos, no cómo buscarlo").
- Ejemplos clásicos:
- SQL:
SELECT nombre, salario FROM empleados WHERE departamento = 'IT' AND salario > 3000; - HTML / CSS: Describe la estructura y diseño visual de la interfaz.
- Prolog / Programación Lógica: Conjuntos de hechos y reglas lógicas evaluadas por un motor de inferencia.
- SQL:
3. Ejemplos de Paradigmas #
Paradigma Imperativo y Procedimental #
Ejemplo en C: calcular la suma de los números del 1 al 5.
1#include <stdio.h> 2 3int main() { 4 int suma = 0; 5 6 for (int i = 1; i <= 5; i++) { 7 suma = suma + i; 8 } 9 10 printf("Resultado: %d\n", suma); 11 12 return 0; 13}
Aquí indicamos paso a paso cómo obtener el resultado: crear una variable, recorrer los números y modificar suma en cada iteración.
Paradigma Orientado a Objetos (POO) #
Ejemplo en Java: representar una cuenta bancaria mediante un objeto.
1class CuentaBancaria { 2 3 private double saldo; 4 5 public CuentaBancaria(double saldoInicial) { 6 saldo = saldoInicial; 7 } 8 9 public void ingresar(double cantidad) { 10 saldo += cantidad; 11 } 12 13 public double getSaldo() { 14 return saldo; 15 } 16} 17 18public class Main { 19 20 public static void main(String[] args) { 21 22 CuentaBancaria cuenta = new CuentaBancaria(1000); 23 24 cuenta.ingresar(500); 25 26 System.out.println(cuenta.getSaldo()); 27 } 28}
Aquí agrupamos datos y comportamiento dentro de un objeto:
1CuentaBancaria 2 │ 3 ├── estado 4 │ └── saldo 5 │ 6 └── comportamiento 7 ├── ingresar() 8 └── getSaldo()
Paradigma Funcional #
Ejemplo en JavaScript: obtener el doble de los números pares.
1const numeros = [1, 2, 3, 4, 5, 6]; 2 3const resultado = numeros 4 .filter(numero => numero % 2 === 0) 5 .map(numero => numero * 2); 6 7console.log(resultado);
Resultado:
1[4, 8, 12]
En lugar de modificar variables mediante un for, encadenamos transformaciones de datos:
1[1, 2, 3, 4, 5, 6] 2 3 │ filter 4 ▼ 5 6 [2, 4, 6] 7 8 │ map 9 ▼ 10 11 [4, 8, 12]
Además, las funciones:
1numero => numero % 2 === 0 2numero => numero * 2
se pasan como argumentos a otras funciones (filter y map).
Paradigma Declarativo #
Ejemplo en SQL: obtener los empleados del departamento de informática cuyo salario sea superior a 3000 €.
1SELECT nombre, salario 2FROM empleados 3WHERE departamento = 'IT' 4AND salario > 3000;
Nosotros indicamos qué queremos obtener, pero no explicamos cómo debe recorrer la tabla:
1QUEREMOS: 2 3empleados 4 │ 5 ├── departamento = IT 6 │ 7 └── salario > 3000 8 │ 9 ▼ 10 nombre + salario
El sistema gestor de bases de datos decide internamente cómo ejecutar la consulta, qué índices utilizar, en qué orden acceder a las tablas, etc.
Paradigma basado en reglas / lógico #
Ejemplo en Prolog:
1padre(juan, pedro). 2padre(pedro, ana). 3 4abuelo(X, Z) :- 5 padre(X, Y), 6 padre(Y, Z).
Podemos preguntar:
1?- abuelo(juan, ana).
Y Prolog responde:
1true
Nosotros hemos definido hechos y reglas, no un algoritmo paso a paso para buscar la solución.
4. Comparativa Práctica: Filtrar y Duplicar Números Pares #
Resumen del tema
Conceptos clave #
- Imperativo vs Declarativo: el imperativo detalla el flujo de control y las mutaciones de memoria paso a paso; el declarativo describe la meta deseada.
- Procedimental: estructuración modular en funciones y bloques condicionales.
- POO: encapsula estado y comportamiento en clases y objetos con herencia y polimorfismo.
- Funcional: funciones puras, inmutabilidad y transformaciones declarativas (
map,filter,reduce). - Multiparadigma: los lenguajes contemporáneos permiten combinar lo mejor de la POO con técnicas funcionales para escribir software más limpio y mantenible.
Qué debes recordar #
Dominar los diferentes paradigmas te permite elegir el enfoque mental más simple y natural para cada tipo de problema computacional.