2. Taxonomía General: Imperativo vs. Declarativo
¿Existe una única forma de resolver un problema? La taxonomía de lenguajes organiza las herramientas computacionales según su filosofía conceptual de ejecución: indicarle a la máquina el camino exacto de pasos (CÓMO) o describir las propiedades del resultado esperado (QUÉ).
PARADIGMA IMPERATIVO: La Receta de Cocina
Explica CÓMO freír un huevo detallando cada micro-paso:
- Tome la sartén del estante.
- Encienda la hornilla a fuego medio.
- Vierta 10 ml de aceite y espere a que caliente.
- Rompa la cáscara del huevo y viértalo.
- Retire tras 3 minutos de cocción.
PARADIGMA DECLARATIVO: El Pedido en RestaurANTE
Usted se sienta frente al mesero y solo describe QUÉ desea:
"Por favor, tráigame un huevo frito con sal."
Al cliente no le compete saber qué marca de sartén usó el chef, a qué temperatura estaba la hornilla ni qué cocinero lo preparó. Solo le interesa que el resultado final cumpla las condiciones.
Foco: El resultado deseado. La ejecución queda delegada al sistema.| Rama Taxonómica | Sub-Familia | Mecanismo Central | Lenguajes Representativos |
|---|---|---|---|
| IMPERATIVO (El CÓMO) |
Procedural | Secuencia de instrucciones, rutinas, variables mutables. | C, Pascal, FORTRAN, Assembly |
| IMPERATIVO | Orientado a Objetos | Encapsulamiento, clases, herencia, paso de mensajes. | Java, C++, C#, Smalltalk |
| DECLARATIVO (El QUÉ) |
Funcional | Funciones matemáticas puras, inmutabilidad, cálculo lambda. | Haskell, LISP, Clojure, ML |
| DECLARATIVO | Lógico | Predicados, hechos, reglas lógicas, unificación y backtracking. | Prolog, Datalog, Mercury |
| DECLARATIVO | Consultas / DSL | Definición formal de conjuntos de datos o interfaces. | SQL, HTML, React JSX |
| MULTIPARADIGMA | Híbridos Modernos | Combinan POO, imperativo y programación funcional según convenga. | Python, JavaScript, Java 8+, Rust |
En el paradigma imperativo, el desarrollador asume la responsabilidad total de guiar a la CPU paso a paso. Se sustenta en tres principios fundamentales:
Control Explícito de Flujo
Se manipulan manualmente bifurcaciones y ciclos de repetición mediante estructuras condicionales (if / else), bucles controlados (for, while) y selección múltiple (switch).
Estado Mutable (Mutable State)
Las variables son casillas de memoria cuyo contenido se sobreescribe durante la ejecución: x = x + 1. El valor depende del instante temporal de lectura.
Secuencia Estricta
El orden cronológico de las líneas altera el resultado. Cambiar de posición dos operaciones puede invalidar el estado del sistema o generar errores graves de punteros nulos.
// Ejemplo de suma acumulada en C (Diapositiva 16)
int suma = 0; // 1. Estado inicial mutable
for (int i = 1; i <= 5; i++) { // 2. Control explícito del contador
suma += i; // 3. Modificación del estado en cada ciclo
}
printf("Resultado: %d\n", suma); // Resultado final: 15
- Control directo y absoluto sobre hardware y recursos de memoria.
- Facilidad intuitiva para modelar algoritmos clásicos y secuenciales.
- Máximo rendimiento en aplicaciones críticas en tiempo real.
- Mayor cantidad de líneas de código (verboso).
- Propenso a errores sutiles por mutación inesperada del estado global.
- Alta dificultad para ejecución paralela y concurrente sin bloqueos (deadlocks).
En el paradigma declarativo, el programador expresa condiciones, relaciones y transformaciones matemáticas. La maquinaria subyacente (el compilador, el motor de base de datos o el runtime) determina la estrategia de ejecución óptima.
-- Ejemplo SQL (Slide 19): Solo especificamos qué registros deseamos
SELECT nombre, salario
FROM empleados
WHERE salario > 50000;
/* El desarrollador NO programa:
- Cómo recorrer los bloques del disco duro
- Si usar un B-Tree, hash index o escaneo secuencial
- Cómo paralelizar la búsqueda en múltiples núcleos */
// JavaScript Funcional Declarativo (Slide 19)
const numeros = [1, 2, 3, 4, 5, 6, 7, 8];
// Declaramos la condición requerida mediante predicado
const pares = numeros.filter(n => n % 2 === 0);
// Resultado: [2, 4, 6, 8] sin escribir un solo bucle manual
| Criterio Técnico | Paradigma Imperativo | Paradigma Declarativo |
|---|---|---|
| Pregunta Clave | ¿Cómo debe hacerse cada paso? | ¿Qué resultado se desea obtener? |
| Control de Flujo | Explícito mediante bucles (for, while) y saltos condicionales. |
Implícito; delegado al motor de inferencia o librerías de orden superior. |
| Estado de Memoria | Mutable: las variables sobreescriben su valor en tiempo de ejecución. | Inmutable o fuertemente controlado: se generan nuevos flujos de datos. |
| Nivel de Abstracción | Bajo a medio: cercano al modelo de la máquina de Von Neumann. | Alto: cercano al razonamiento lógico, matemático o descriptivo humano. |
| Concurrencia | Compleja: requiere semáforos, bloqueos de hilos (mutex) para evitar colisiones. | Nativa y segura: la inmutabilidad permite paralelismo masivo sin bloqueos. |
El Caso de Estudio en Java: Del Bucle For a la Stream API (Slide 22)
Java incorporó en su versión 8 el soporte funcional mediante la API de Streams, permitiendo apreciar ambos estilos dentro del mismo lenguaje:
// Filtro imperativo clásico
List<Integer> pares = new ArrayList<>();
for (Integer n : numeros) {
if (n % 2 == 0) {
pares.add(n); // mutación de lista
}
}
// Mismo resultado con Stream API
List<Integer> pares = numeros.stream()
.filter(n -> n % 2 == 0)
.toList();
// Sin variables acumuladoras ni ciclos manuales