Y he podido asistir, dada mi edad, a casi toda su historia (me perdí un poco del principio) y a cómo ha ido evolucionando. Y lo cierto es que la transformación es enorme. Ha cambiado en filosofía, lenguajes, herramientas y requisitos profesionales del desarrollador.
En este post quisiera revisar esa evolución, y lo que los cambios suponen, de bueno y de malo
Un análisis en cinco fases
Y, para ello, propongo identificar las fases principales de la evolución.
Que yo sepa, no existe ninguna forma de marco concreta para clasificar esta evolución de la forma de construir software, (aunque sí se habla a veces de generaciones, sobre todo tercera y cuarta, pero con base en mi percepción personal, hablaría de cinco fases, a saber:
- Fase 1: código máquina
- Fase 2: ensamblador
- Fase 3: lenguajes de alto nivel
- Fase 4: 'low-code' / 'no-code'
- Fase 5: 'vibe coding' o 'prompt based coding'
Veamos brevemente lo que significa y aporta cada una de ellas.
Fase 1: código máquina
En esta fase, que sinceramente creo que pocos desarrolladores han vivido salvo, como mucho, durante sus estudios, se trabaja directamente con el hardware, con el microprocesador y se expresa el programa en los famosos unos y ceros que caso nadie ha visto.
Es una programación muy, muy cercana al hardware, e implica conocer en detalle el microprocesador, sus registros, las instrucciones que maneja y cómo se codifican, las direcciones de la memoria etc. Los programas son, a poco que el programador sepa lo que hace, extraordinariamente eficientes en recursos computacionales y rápidos en ejecución, pero eso sí, son muy dificultosos de desarrollar y depurar y, por tanto, en general de un alcance muy modesto.
Fase 2: ensamblador
En realidad, es muy similar a la anterior, pero ahora hay un cierto lenguaje, el ensamblador, que al menos expresa las instrucciones mediante nemónicos textuales (típicamente de tres letras) con lo que, aunque con criterios de hoy en día siguen siendo enormemente crípticos, para su momento fueron una gran aportación en cuanto a claridad.
Fase 3: lenguajes de alto nivel
Son, quizá, el primer tipo de lenguajes ampliamente conocidos. En ellos el lenguaje de programación se basa en formas textuales más o menos destiladas del inglés, pero circunscritos a una serie de instrucciones muy concretas y con una estructura en general muy bien definida. Aunque hable de una forma de inglés no tiene nada que ver con el lenguaje natural: se trata de lenguajes muy acotados, muy estructurados y muy ligados a gramáticas estrictas.
Introducen ya los tipos de datos, las variables, las estructuras de control del tipo de bucles y condiciones o la capacidad de crear funciones. Con el tiempo, con el auge de la orientación a objetos, se introduce también esta idea de los objetos (que unen datos y comportamiento) y a capacidad de crearlos y utilizarlos.
Son lenguajes ya independientes del microprocesador e incluso del sistema operativo en que se ejecutan y un programa auxiliar, el compilador o el intérprete según el caso, se encarga de traducir esas instrucciones textuales de alto nivel al código máquina.
Se fueron acompañando de entornos de desarrollo del tipo IDE ('Integrated Development Environment') que incluyen capacidades de control y organización del código, capacidades de depuración, ayudas, etc.
En esta categoría caben casi todos los lenguajes de programación más conocidos, desde algunos más antiguos como COBOL o Pascal, y pasando por Basic, C, C++, Java o python, por decir algunos.
El salto de productividad es inmenso respecto a la programación en ensamblador, una productividad que se refuerza por la posibilidad de creación y reutilización de librerías de funciones u objetos que proporcionan, ya empaquetadas y listas para ser usadas, capacidades más o menos sofisticadas. Creo que es con base estos lenguajes que se produce el verdadero 'boom' del software.
Interludio: los lenguajes de cuarta generación 4GL
No los he llegado a proponer como una fase diferenciada, pero por encima de los lenguajes de alto nivel (que a estos efectos se consideran de tercera generación), proporcionan mayores niveles de abstracción y un enfoque algo más declarativo, normalmente orientados a software de características bastante comunes y estructuradas como la gestión de bases de datos.
Hay quien los considera como un antecedente de lo que veremos a continuación: el 'low-code'.
Fase 4: low-code / no-code
La fase 4 nos conduce a la filosofía y soluciones 'low-code' o, en su extremo, 'no-code'.
La idea es que el desarrollador ya no trabaje con código fuente (que se expresa en un lenguaje de tercera generación) o que lo haga en la menor medida posible. ¿Cómo se consigue eso? Pues proporcionando entornos de desarrollo gráficos o semi-gráficos, donde con frecuencia los bloques de ejecución se representan por cuadrados o círculos, que se unen mediante líneas o flechas para representar una lógica completa. Además, el entorno de desarrollo ofrece ya una amplia librería (normalmente ampliable) de bloques constructivos
En general el desarrollo tiende a convertirse en 'dibujar' la lógica de ejecución complementada por la configuración (habitualmente mediante cuadros de diálogo) de los parámetros y variantes de ejecución de cada uno de los bloques constructivos, así como la definición de variables.
En los casos más extremos ('no-code') no es necesario incluir código fuente tradicional y en otros casos ('low-code') sí existen determinados puntos donde se complementa la lógica, digamos gráfica, con pequeños elementos de lenguaje de programación de tercera generación.
Esta filosofía es cada vez más común para construir todo tipo de soluciones, pero, por citar algunas muy representativas, tendríamos, en el ámbito de la automatización, casi todos los entornos RPA ('Robotic Process Automation') o BPMS ('Business Process Management Systems'), así como soluciones de automatización de workflow (como Make o N8N) e, incluso, algún entorno de construcción de agentes IA como LangFlow. También es común, por ejemplo, en visualizadores de datos como Power BI.
En este salto, no es ya que nos hayamos alejado del hardware y el microprocesador, es que incluso nos hemos alejado de los lenguajes de programación como tales, si entendemos los lenguajes de programación como algo con base textual. Incluso, gran parte de la lógica detallada, viene resuelta por los bloques constructivos disponibles sinq ue el desarrollador la conozca en detalle, sino sólo por su comportamiento externo.
Fase 5: Vive coding o 'prompt based coding'
El último salto, es la creación de software a partir de prompts usando herramientas de inteligencia artificial generativa. En el primer post de este blog que dediqué al 'vibe coding', comentaba la diferenciación entre el uso de inteligencia artificial como una especie de ayuda o copiloto, lo que Addy Osmani denominaba 'Ingeniería de software asistida por IA' frente al uso de la IA para construir toda la aplicación, siendo esto último a lo que asignaba el término 'Vibe coding'.
En realidad, si usamos la IA como copiloto, estamos realmente reforzando una de las dos fases anteriores (lenguaje de alto nivel o 'low-code'/'no-code') pero no sería una fase realmente diferenciada.
Lo que considero como una fase diferenciada es cuando usamos la herramienta para la generación completa de aplicaciones o módulos a partir de prompts en lenguaje natural. Como en este caso la forma de actuar que tiene el desarrollador es únicamente mediante 'prompts', me he querido inventar el término 'prompt based coding'.
En este caso el alejamiento ya es total: el desarrollador no es que no conozca el hardware o el sistema operativo, y no es ya que no utilice un lenguaje de programación, es que, incluso, salvo que se preocupe por ello, hasta desconoce la lógica interna del software que ha generado o cómo está estructurado. El desarrollador, en teoría, se centra sólo en la necesidad, que expresa mediante lenguaje natural, no en los detalles internos del software.
Se trata de una fase probablemente poco madura en estos momentos y que hay que ver hasta dónde es capaz de llegar, pero, en teoría, es una fase de altísima productividad y, además, casi al alcance de cualquiera, una fase donde el propio término 'desarrollador', al menos tal y como lo hemos entendido hasta ahora, puede que pierda sentido.
Consecuencias
A medida que se avanza en las diferentes fases, creo que se producen los siguientes efectos:
- Se aumenta (y mucho) la productividad del desarrollo software
- Se baja la barrera de entrada (los conocimientos y la especialización necesarios) para crear software
- El desarrollador pierde conocimiento del detalle de lo que está haciendo (el hardware, el sistema operativo, las lógicas internas, etc)
- Debido a esa pérdida de conocimiento (y gestión) del detalle, en general el software generado es menos eficiente en el uso de recursos computacionales: memoria, tiempo de CPU, disco, etc
En general, la evolución de la industria ha apostado por los dos primeros beneficios (productividad y bajada de la barrera de entrada) frente a los dos últimos inconvenientes (perdida de conocimiento y menor eficiencia en recursos computacionales).
Voy pararme un momento en dos aspectos.
La productividad y las barreras de entrada
En efecto, el gran beneficio de esta evolución es, sobre todo, la altísima mejora de productividad en la construcción de software, no sólo en cuanto a cantidad de código creado sino en cuanto a potencia y capacidades de las soluciones generadas. Por ejemplo, hace 20 o 30 años, hacer la interfaz de usuario (las ventanas, por entendernos) de un sistema, era tremendamente trabajoso... y hoy es casi trivial en algunos casos.
A esto se une, especialmente en las dos últimas fases, en unos menores requisitos, una menor cualificación, para ser creador de software, llegándose ya hace unos años al concepto acuñado por Microsoft de 'Citizen developer' (un concepto muy ligado al 'low-code') en que ya parte del software empresarial podría ser creado, no por desarrolladores profesionales del departamento de IT, sino por profesionales del ámbito del negocio (ventas, marketing, operaciones, etc)
El deskilling
Sin embargo, ese menor conocimiento requerido supone en parte un peligro para el propio software en el sentido de que el desarrollador puede ser mucho menos capaz de hacer un software eficiente, escalable e incluso seguro, o que le puede costar depurar los errores más extraños.
De cara al desarrollador, como profesión, el avance en estas fases, muy especialmente la última, pone en riesgo la profesión en sí misma, en riesgo de desaparición o, quizá más probable, de profunda redefinición y, quizá, sólo quizá, menor cualificación y por tanto consideración profesional.
En el fondo, se produce una forma particular de 'deskilling' (término del que he hablado en los dos últimos posts), en que el desarrollador cada vez sabe menos de sistemas, cada vez sabe menos, por supuesto del hardware, pero también sabe menos de las mejores arquitecturas, de los mejores criterios y mejores prácticas de construcción de software. Y eso es un riesgo potencial para la propia calidad del software y para su mantenibilidad y, quizá, un empobrecimiento personal y profesional del desarrollador.
Conclusiones
El desarrollo de software ha sufrido a lo largo de las últimas décadas, una enorme transformación en su forma de realización, una evolución que le ha conducido, a través de cinco fases, a recorrer un camino en el que ha ganado una enorme productividad y sencillez, pero a cambio de una menor eficiencia en recursos computacionales y en una progresiva descualificación técnica de los profesionales que la ejercen.








No hay comentarios:
Publicar un comentario