Programación Estructurada: Disciplina sobre el Control Directo
Dijkstra demostró que el goto sin restricciones es perjudicial. La secuencia, selección e iteración son suficientes para módulos correctos y descomponibles.
Por qué importa
En 1968 Edsger Dijkstra publicó "Go To Statement Considered Harmful", uno de los artículos más influyentes en ciencias de la computación. Demostró matemáticamente que los programas construidos solo con secuencia (sentencias en orden), selección (if/else) e iteración (bucles) pueden descomponerse recursivamente y verificarse formalmente. Los programas con goto sin restricciones no pueden.
Los lenguajes modernos eliminaron el goto, pero los desarrolladores todavía escriben su equivalente espiritual: condiciones profundamente anidadas, banderas booleanas como flujo de control y bucles que simulan saltos. Estos patrones hacen que las funciones sean imposibles de probar en aislamiento e imposibles de razonar de un vistazo. El principio detrás de la programación estructurada aplica hoy: si un humano debe simular la máquina para leer una función, la estructura está luchando contra él.
✗El problema
A flag variable used to break out of a loop is a goto in disguise. Deep nesting makes the control flow impossible to follow without running the code mentally.
Bad
def find_first_even(numbers: list[int]) -> int | None:
found = False
result = None
index = 0
keep_going = True
while keep_going:
if index >= len(numbers):
keep_going = False
else:
if not found:
if numbers[index] % 2 == 0:
result = numbers[index]
found = True
keep_going = False
index += 1
return result
function findFirstEven(numbers: number[]): number | null {
let found = false;
let result: number | null = null;
let index = 0;
let keepGoing = true;
while (keepGoing) {
if (index >= numbers.length) {
keepGoing = false;
} else {
if (!found) {
if (numbers[index] % 2 === 0) {
result = numbers[index];
found = true;
keepGoing = false;
}
}
index++;
}
}
return result;
}
✓La solución
Secuencia, selección y retorno temprano — sin banderas, sin anidamiento. El flujo de control es rastreable en una sola lectura de arriba hacia abajo.
Good
def find_first_even(numbers: list[int]) -> int | None:
for n in numbers:
if n % 2 == 0:
return n
return None
function findFirstEven(numbers: number[]): number | null {
for (const n of numbers) {
if (n % 2 === 0) return n;
}
return null;
}
💡Conclusión clave
Si un lector debe simular la máquina para seguir el flujo de control de una función, el código es programación estructurada hecha incorrectamente — independientemente de si goto aparece en el código fuente.
🔧 Algunos ejercicios pueden tener errores. Si algo parece incorrecto, usa el botón Feedback (abajo a la derecha) para reportarlo — nos ayuda a corregirlo rápido.
Pista: Si no puedes seguir el flujo con una lectura directa, la estructura te está dificultando el trabajo.
✗ Tu versión