Parte 0 — Pensamiento computacional y el método políglota · ⏱️ Duración estimada: 75 min · Nivel: Fundamentos ✅ Clase construida.
Hay dos habilidades que separan a quien programa cosas pequeñas de quien construye sistemas: partir un problema grande en subproblemas manejables (descomposición) y notar cuándo un subproblema ya lo resolviste antes, quizá con otra forma (reconocimiento de patrones). Son las dos caras de una misma moneda: descomponer genera piezas, reconocer patrones evita resolver dos veces la misma pieza. Juntas hacen que la programación escale, que un problema el doble de grande no cueste el cuádruple de esfuerzo.
Esta es la segunda fase de Polya —trazar un plan— llevada a su forma más concreta. Un plan no es más que una descomposición: "para lograr esto, primero haré aquello, luego lo otro". Y una de las tácticas centrales de Polya para trazar planes es preguntarse "¿he visto este problema antes, o uno parecido?". Ese "parecido" es el reconocimiento de patrones. El objetivo de hoy es que conviertas ambas en un hábito deliberado, no en algo que a veces pasa por suerte.
Te piden "generar un reporte de ventas en PDF". Como enunciado es enorme y paraliza: no hay una función generarReportePDF() que baste. Pero descompuesto se vuelve tratable: (1) leer los datos de ventas de algún origen, (2) calcular los totales y agregados, (3) dar formato a esas cifras como texto o tabla, (4) exportar ese contenido a un archivo PDF. Cada una de esas cuatro piezas es un problema conocido, con solución probada, que puedes resolver y verificar por separado. Y hay un premio extra: la estructura "leer → transformar → escribir" que acabas de descubrir reaparece en casi todo el software que escribirás en tu vida. Reconocerla una vez te ahorra reinventarla mil.
Al finalizar, podrás:
| # | Tema | Por qué importa |
|---|---|---|
| 1 | Descomposición | Divide y vencerás: partes pequeñas se resuelven y prueban solas |
| 2 | Reconocimiento de patrones | Reutilizar una solución conocida ahorra trabajo y errores |
| 3 | De subproblema a función | La descomposición prefigura la modularidad (Parte 5) |
Descomponer es dividir un problema en subproblemas más simples, cada uno resoluble y verificable por separado. Su virtud es doble: reduce la carga mental —solo piensas una pieza a la vez— y localiza los errores —si algo falla, sabes en qué pieza mirar—. Cormen dedica un capítulo entero a la técnica de divide y vencerás, que es descomposición en su forma algorítmica más pura: partir el problema en subproblemas del mismo tipo, resolverlos y combinar sus resultados (así funcionan merge sort o la búsqueda binaria). Pero la descomposición no exige que las partes sean del mismo tipo; basta con que cada una sea más pequeña que el todo y se pueda atacar por su cuenta.
Un patrón es una estructura de solución que reaparece en problemas distintos. "Filtrar los elementos que cumplen una condición", "acumular un total recorriendo una colección", "buscar el primero que satisface algo": estas formas surgen una y otra vez bajo disfraces diferentes. Reconocer que un subproblema nuevo tiene la forma de un patrón conocido es lo que evita reinventar la rueda —y, más importante, reinventarla con los mismos bugs que ya alguien resolvió—. Polya llama a esto trabajar por analogía, y lo considera una de las herramientas más potentes del que resuelve problemas: la mayoría de los problemas "nuevos" son variaciones de problemas viejos.
La conexión entre ambas ideas y el código es directa y es una de las columnas del curso: cada subproblema tiende a convertirse en una función, y cada patrón, en una función reutilizable. La abstracción de subproblema —tratar una pieza ya resuelta como una caja negra de la que solo importa qué hace, no cómo— es exactamente lo que SICP identifica como el mecanismo que permite construir programas grandes: encapsulas una solución, le pones nombre y la usas como si fuera una operación primitiva. Descomponer bien hoy es tener funciones bien diseñadas mañana (Parte 5), y reconocer patrones hoy es anticipar el map/filter/reduce de la Parte 4 y los patrones de diseño de la Parte 9.
Descompongamos "calcular el promedio de las notas aprobadas de un curso" y nombremos el patrón de cada pieza:
Problema: promedio de las notas >= 4 (escala de 1 a 7)
Descomposición:
1. filtrar las notas que son >= 4 → patrón: FILTRAR
2. sumar las notas que quedaron → patrón: REDUCIR (acumular)
3. contar cuántas quedaron → patrón: CONTAR
4. dividir la suma entre la cuenta → operación final
Caso límite: si ninguna nota es >= 4, la cuenta es 0
⇒ decidir qué devolver (¿0? ¿"sin aprobados"?)
Tres de las cuatro piezas son patrones con nombre propio —filtrar, reducir, contar— que reaparecerán literalmente en la Parte 4 como filter, reduce y count/len. La cuarta pieza esconde un caso límite (división entre cero si no hay aprobados) que la descomposición hace visible: al separar "contar" de "dividir", saltar el peligro de dividir entre cero se vuelve imposible de ignorar.
Descompón el problema "corregir automáticamente un test de opción múltiple" en tres o cuatro subproblemas y, junto a cada uno, nombra su patrón. Piensa en voz alta: necesitas comparar las respuestas del alumno con las correctas (¿qué patrón es comparar par a par dos listas?), contar los aciertos (¿cuál cuenta?), quizá calcular una nota a partir del conteo. Cuando termines, subraya cuáles de esos patrones ya aparecieron en el ejemplo del promedio. Si descubres que "contar aciertos" es el mismo patrón CONTAR que ya viste, has hecho reconocimiento de patrones de verdad: eso es el objetivo.
| Síntoma / mensaje | Causa y cómo corregirlo |
|---|---|
| Una sola función gigante que hace de todo | No descompusiste. Extrae cada subproblema a su propia función con nombre |
| Copiar y pegar el mismo bloque en tres sitios | No reconociste el patrón repetido. Nómbralo y conviértelo en una función reutilizable |
| Descomponer hasta el infinito, funciones de una línea inútiles | Descomposición sin criterio. Detente cuando cada pieza quepa en tu cabeza y se pruebe sola |
| No sabes por dónde empezar un problema grande | Intentas resolverlo entero de golpe. Pártelo primero; ataca una pieza después |
❓ ¿Hasta dónde debo descomponer? Hasta que cada parte quepa cómodamente en tu cabeza y se pueda probar por sí sola. Ni menos (funciones que hacen cinco cosas) ni más (funciones de una línea que solo añaden ruido). El criterio es humano, no mecánico: si puedes explicar la pieza en una frase, tiene el tamaño correcto.
❓ ¿Los "patrones" de esta clase son los "patrones de diseño" famosos? No, o todavía no. Aquí hablamos de estructuras de solución elementales: filtrar, acumular, buscar. Los patrones de diseño formales (Observer, Factory, Strategy...) son construcciones mayores que llegan en la Parte 9. Pero el músculo es el mismo: reconocer que "esto ya lo vi con otra forma".
❓ ¿Descomponer no hace el programa más lento por tantas funciones? En la práctica, casi nunca: los compiladores e intérpretes optimizan bien las llamadas, y la claridad que ganas vale mucho más que los nanosegundos que podrías perder. Primero descompón para entender; optimiza solo donde midas que hace falta (clase 009).
⏮️ Clase 003 · 📂 Parte · 📚 Índice · 🌐 Atlas · Clase 005 ⏭️