Como decíamos en la introducción al curso de programación, la programación abarca un amplio espectro de avances tecnológicos y contribuciones intelectuales que han sentado las bases para la disciplina tal y como la conocemos hoy en día.
No me parecería bien hacer un curso de introducción a la programación sin dedicar al menos un artículo a ve (brevemente), la historia de la evolución de la programación.
Desde las primeras máquinas hasta los modernos sistemas actuales, cada hito en esta cronología ha influido en la forma en que entendemos y aplicamos los principios de la programación.
Etapa pre-ordenadores
El origen de la programación se remonta a los albores de la humanidad, cuando los seres humanos buscaban formas de automatizar tareas repetitivas. Desde la prehistoria encontramos máquinas que empleaba energía para realizar trabajos de forma automática.
Encontramos sistemas automáticos de regadío en Babilonia, sobre el 2000 a.C. También es sabido que los griegos empleaban sistema hidráulicos y neumáticos. Los egipcios disponían de mecanismos realmente ingeniosos en sus templos.
Muchas de esas máquinas tenían un comportamiento automático (eran automatismos) y lógicamente, también se programaban. En la antigüedad, las primeras formas de programación involucraban la configuración de máquinas mecánicas, neumáticas e hidráulicas.
Durante la edad media, como en casi todos los campos del conocimiento se produce un parón importante. No hasta el renacimiento y la revolución industrial donde los avances en automatización empiezan a aparecer de nuevo.
Revolución industrial
En 1725, Basile Bouchon, hijo de un fabricante de órganos francés, adaptó el concepto de los mecanismos de relojería utilizados en las cajas de música para operar un telar a través de una cinta perforada. Este invento fue perfeccionado en 1728 por su asistente, Jean-Baptiste Falcon, quien utilizó una serie de tarjetas perforadas interconectadas.
Poco después, en 1745, Jacques de Vaucanson, ingeniero e inventor francés de autómatas mecánicos, aplicó sus conocimientos y creó el primer telar automático. Sus conocimientos en mecanismos automatizados fueron cruciales para el desarrollo de la programación y sentaron las bases para futuros avances.
Sobre la base de estos dos inventos, en 1801 Joseph Marie Jacquard crea un famoso telar mecánico de tarjetas perforadas. Cada tarjeta perforada representaba una instrucción específica, lo que permitía la creación de patrones complejos sin la necesidad de una intervención humana constante
A medida que la tecnología avanzaba, los ingenieros y matemáticos exploraban formas de automatizar cálculos complejos. En el 1840, Charles Babbage desarrolló la “Máquina Analítica”, considerada uno de los primeros intentos de crear un ordenador programable (aunque la Máquina Analítica nunca se construyó completamente, sentó las bases para la concepción de los primeros principios de programación).
En la segunda mitad del siglo XIX, las tarjetas perforadas se convirtieron en una forma popular de programación en los campos de la estadística y el censo. Las tarjetas perforadas permitían almacenar información de manera estructurada y realizar operaciones utilizando máquinas electromecánicas. Esta tecnología desempeñó un papel crucial en la evolución de la programación, proporcionando un método para ejecutar instrucciones complejas.
Los primeros ordenadores
La verdadera revolución en la historia de la programación llegó con el surgimiento de los primeros ordenadores electrónicos en la década de 1940. Durante la Segunda Guerra Mundial, Alan Turing y su equipo desarrollaron el Colossus, una máquina diseñada para descifrar los códigos de la máquina de cifrado alemana Enigma.
Rápidamente los ordenadores aumentaron su potencia, mientras que disminuían su tamaño. A ello contribuyeron la invención de nuevas tecnologías como los transistores, que sustituyeron a las válvulas de vacío.
En esa época, los programadores tenían que escribir directamente en código máquina, que consiste en instrucciones numéricas directamente entendibles por el hardware de la computadora. Este enfoque era extremadamente laborioso y propenso a errores.
Para abstraerse de esta complejidad en 1947 se desarrolló el lenguaje ensamblador, que permitía a los programadores escribir instrucciones en forma de mnemotécnicos más legibles. Aunque el ensamblador seguía estando muy cerca del lenguaje máquina, proporcionaba una capa de abstracción que facilitaba el desarrollo de programas.
Poco después, a principio de la década de 1950 surgieron los lenguajes de alto nivel, diseñados para ser más accesibles y fáciles de usar que el ensamblador. Estos lenguajes proporcionaban una abstracción aún mayor, permitiendo a los programadores expresar conceptos y algoritmos de manera más cercana al lenguaje humano.
En paralelo, se desarrollaban la teoría y fundamentos de muchos paradigmas que conocemos actualmente. Por ejemplo, se desarrollan las bases de la lógica combinacional y de la Programación Funcional, cuyo origen se remonta a la década de 1930.
En lugar de centrarse en los objetos y su interacción, la programación funcional se basa en el concepto de funciones puras, que toman una entrada y generan una salida sin tener efectos secundarios.
Posteriormente, entre 1950 y 1960 surge uno de los paradigmas de programación más influyentes. Programación Orientada a Objetos (POO). La POO se basa en la idea de que los programas deben modelar objetos del mundo real, con características (atributos) y comportamientos (métodos) asociados.
Época moderna
Con la popularización de los ordenadores y su inclusión en el campo doméstico, la teoría de programación continua desarrollándose hasta lo que conocemos hoy en día.
Un hito importante eso, como todos sabemos, la aparición de lo que hoy llamamos Internet. Esto es debido a la mejora y complejización de los sistemas de comunicación entre ordenadores. Con la aparición de la www, surge nuevas necesidades para el desarrollo del software.
A medida que el software cada vez se complica más, con aplicaciones más complejas, aplicaciones móviles, virtualización, cloud computing, el software también se vuelve más complejo. Además, la necesidad de interface de usuario más ricos y usables cobra una nueva importancia.
Esto hace que surjan nuevos paradigmas como la programación reactiva o la inmutabilidad, unit testing, frameworks, bibliotecas, dependencias, devops, y muchas otras herramientas destinadas a gestionar la complejidad de los proyectos.
En la actualidad, el desarrollo de software actual es un ámbito de la tecnología que aborda muchos aspectos, incluido diseño, psicología, gestión de proyecto. Como vemos, aspectos más allá del componente “matemático” que tradicionalmente tenía, y que también iremos viendo en este curso.