16 clases · rango 057–072 · clases de código · nivel intermedio · ~40 h (cronograma)
🧭 Decidir, repetir y fallar: el flujo del programa y sus formas en diez lenguajes.
Un programa que solo calcula expresiones no es todavía un programa. La Parte 4 añade las dos operaciones que lo convierten en uno —decidir y repetir— y termina con la tercera que nadie llama control de flujo y lo es: fallar.
El recorrido va de lo más concreto a lo más expresivo. Empieza por la condición y sus formas (if, ternario, switch, match), sigue por los bucles en sus tres sabores (por condición, por rango, por colección) y llega a la iteración perezosa y a las comprensiones, donde el «cómo recorro» empieza a desaparecer del código. Después, map/filter/reduce y la recursión muestran que se puede repetir sin escribir un solo bucle.
El cierre son las dos filosofías del error: la excepción, que salta por la pila hasta quien sepa atenderla, y el resultado como valor, que obliga a mirarlo en el sitio. Es una de las divisiones más profundas entre los lenguajes del núcleo y se ve mejor con las dos implementadas lado a lado.
La Parte 3 completa: booleanos (046), operadores (055) y entrada/salida (056) se usan en todas las clases de esta parte.
Resultados comprobables: si no puedes hacerlos, la parte no está cerrada.
if, switch y match con un criterio explícito y no por costumbre.map/filter/reduce.Result, y defender cuál conviene.Las clases están agrupadas en bloques por la razón que las une. El orden es secuencial: cada una asume la anterior.
De la condición booleana a la coincidencia de patrones, pasando por las guardas y el switch.
&&, ||) no es una optimización: es semántica observable, porque determina si el segundo operando —y sus efectos— llega a evaluarse.if / else if / else elige entre alternativas mutuamente excluyentes. Aquí se ve por qué el anidamiento profundo es un problema de comprensión y no de estilo, y cómo cada lenguaje lo aplana con recursos distintos.if como sentencia y como expresión separa a Rust y Kotlin de C y Java, y explica por qué unos necesitan el operador ternario y otros no.switch nace de una necesidad concreta: elegir entre muchos valores exactos sin una escalera ilegible de else if. El fallthrough —caer al siguiente caso— es la trampa clásica, y los lenguajes modernos la han invertido por defecto.switch: en vez de preguntar «¿es igual a esta constante?», pregunta «¿tiene esta forma?», y desestructura al mismo tiempo que decide. Es la puerta de entrada a los tipos algebraicos.Los tres sabores de bucle, la evaluación perezosa y las comprensiones.
while es el bucle en su forma más pura: repetir mientras algo siga siendo cierto, sin presuponer contador ni número de vueltas. Es más fundamental que el for, y por eso es donde se estudian el invariante y la condición de parada.for cubre el caso más común: saber de antemano cuántas veces o sobre qué rango. La distancia entre el for clásico de C y el for-range de Go o Python muestra cuánta ceremonia era accidental.x de la lista tales que x es par»— viene de la notación matemática de conjuntos, y es el punto donde lo imperativo empieza a ceder terreno.Funciones de orden superior y recursión: el mismo trabajo sin escribir el recorrido.
map, filter y reduce son la prueba de que una función puede recibir otra función. Con esos tres verbos se expresa la mayoría de los bucles que escribes, y se hace visible qué parte era recorrido y qué parte era lógica.Saltos controlados y las dos grandes filosofías del manejo de errores.
break, continue, return y el proscrito goto son salidas del flujo natural. Ninguno es malo por sí mismo: lo que importa es si hacen el código más fácil o más difícil de razonar, y esa evaluación se puede argumentar.Result en Rust, error en Go, Either en la familia ML. El error deja de ser un canal aparte y pasa a ser un valor que el compilador te obliga a mirar.| Se suele creer | Lo que ocurre en realidad |
|---|---|
«match es un switch más bonito.» |
El switch compara con constantes; el match compara formas y desestructura. Son operaciones distintas. |
| «La recursión siempre es más elegante.» | Es más natural sobre estructuras recursivas y desastrosa sobre secuencias largas en lenguajes sin optimización de cola. |
| «Las excepciones son el manejo de errores moderno.» | Go y Rust demuestran lo contrario: el error como valor es igual de moderno y mucho más visible en la firma. |
python scripts/verificar_equivalencia.py NNN) y comprueba tú mismo que coinciden. Fuerza después un caso límite y observa quién se rompe primero.primos.md para ver el mismo programa en la familia de cada lenguaje: es donde el concepto deja de estar atado a diez nombres concretos.Cada clase cita estos libros en su sección de referencias. No se reproduce su contenido: la redacción es original.
Con flujo y datos elementales, la Parte 5 introduce la abstracción que lo ordena todo: la función y el módulo.