Desarrollo de software, programación e inteligencia artificial
Si tomáramos el proceso de desarrollo de software y lo destiláramos hasta quedarnos con su esencia, uno podría concluir que éste no consiste en otra cosa sino en capturar un conjunto de requisitos funcionales escritos en leguaje humano y traducirlos a un lenguaje que pueda entender una máquina, la cuál se encargaría de ponerlos en marcha.
Podría también concluir que cada vez que se añade, elimina o modifica un requisito tendriamos un sistema completamente nuevo, independiente del que existiera anteriormente. En cada momento de su historia, el software no sería otra cosa más que el conjunto de requisitos que lo conforman en ese mismo momento traducidos a algún tipo de lenguaje “máquina”.
Podría además asumir que el histórico es irrelevante. Lo que importa es cuáles son los requisitos hoy, independientemente de cuáles fueran ayer. O, dicho de otra forma, desde un punto de vista puramente teórico, cada vez que se introdujera un cambio en las especificaciones del sistema deberíamos ser perfectamente capaces de reconstruirlo desde cero.
Sin embargo, como toda teoría que se precie, ésta tiene sus limitaciones cuando se intenta aplicar en el mundo real®.
El problema del código mantenible
Una limitación que tenemos los humanos y hace inviable lo descrito más arriba es que los humanos somos lentos escribiendo código.
Muuuuuuyyyyyyy leeeeeeennnnntoooooos.
Imaginemos que cada vez que queremos añadir o modificar una funcionalidad tuviéramos que reescribir toda la aplicación desde cero.
Esto hace que, aunque desde el punto de vista teórico el historial del código nos dé igual, desde el punto de vista práctico es fundamental que carguemos con él. Un histórico cada vez más grande.
En realidad lo que hacemos hoy en día, como es obvio, no es reescribir nuestras aplicaciones desde cero sino aplicar pequeños cambios a nuestra base de código.
Es este “pequeño” matiz el que nos obliga a hacer código mantenible. Código que podamos modificar de forma lo más sencilla posible para poder “traducir” los nuevos requisitos del software y así poder realizar un desarrollo sostenible durante toda la vida del producto.
Y es esta mantenibilidad la que, en gran medida y durante más de 40 años, la industria ha intentado maximizar mediante la creación y uso de patrones y principios de diseño como MVC o SOLID, principios de desarrollo como YAGNI o KISS, o incluso diseño de flujos de trabajo como Trunk Based Development… todo con el objetivo de hacer sostenible el desarrollo.
Y es que si nos paramos a pensar, el código en realidad no es más que una necesidad que no aporta valor ninguno al producto final. Si pudiéramos comunicarnos directamente con la máquina en lugar de tener que traducir nuestras especificaciones (en lenguaje humano) a ceros y unos, no dudaríamos ni un segundo en quitarnos de en medio todas esas capas intermedias en forma de lenguajes de programación, compiladores, sistemas operativos y demás (junto con todas las tareas asociadas a ellos).
Y es que si no tuviéramos que dedicar tiempo a programar, podríamos dedicar tiempo a todas las demás tareas del desarrollo de software que sí aportan verdadero valor. Porque el desarrollo de software es mucho más que programar.
IAs al rescate
Si el problema fundamental a nivel técnico del desarrollo de software (el mantenimiento del código) viene derivado de nuestra incapaz de recrear un sistema entero desde cero debido a la velocidad de codificación, ¿qué pasaría si utilizamos una IA para escribir dicho código?
Una vez más, poniéndonos en un plano teórico, esto resolvería la causa del problema (o al menos cambiaría la escala del mismo). Pasaríamos de necesitar días, semanas, meses o incluso años en reescribir toda una base de código a necesitar segundos, horas o días.
Y, además, haría innecesaria toda esa capa múltiple que comentábamos antes en forma de lenguajes de programación y derivados. Si es la IA la encargada de regenerar el sistema… ¿para qué necesitaríamos ser capaces de entender el código que genera? ¿Acaso necesitamos entender el bytecode que genera la máquina virtual de java?
Si bien es cierto que lo más seguro es que seguiríamos necesitando en algunos puntos del software programación humana, ésta quedaría relegada a puntos muy concretos del mismo. Por ejemplo, a la comunicación con la propia IA, o quién sabe, si a ciertas partes del software que necesitáramos auditar por obligación regulatoria.
Pero, ¿cómo de viable es esto hoy en día?
Las limitaciones actuales de las IAs generativas
Una vez más nos tenemos que enfrentar al mundo real®
Éstas son las principales limitaciones que le encuentro hoy a las IAs generativas.
(Disclaimer: Ésta es la parte de este artículo que peor va a envejecer casi con total seguridad. Visto cómo evoluciona este mundo puede incluso que mientras escriba estas líneas algunas de estas limitaciones ya se hayan resuelto. Pero qué demonios, ¡me la juego!)
- El tamaño del contexto que aceptan hoy en día las IAs no es suficientemente grande como para poder pasarle todos los requisitos de una aplicación. Lo esperable es que esto se resuelva más pronto que tarde.
- Las IAs generativas pueden aprender a generar código a partir de conjuntos de datos de código existente, pero a menudo tienen dificultades para comprender la lógica subyacente detrás del código y cómo se relaciona con otros componentes del software. Esto puede llevar a la generación de código que no funciona como se esperaba o que tiene errores en su funcionamiento. Dicho de otra forma: las IAs pueden generar código que compile, pero que no funcione como se espere. Y cuanto mayor es la complejidad del problema que le damos, más probable es que nos devuelva código “compilable” que no funciona bien.
Estas limitaciones hacen que hoy en día estemos todavía “lejos” de poder pedirle a una IA que nos haga software. Todavía no estamos en el momento en que podamos prescindir de programación por parte de humanos.
¿En qué me pueden ayudar HOY las IAs?
A pesar de que hoy por hoy todavía no podamos delegar el trabajo de programación a las IAs hay ciertas tareas en las que sí nos pueden ayudar:
- Generación de código concreto como métodos, tests o expresiones regulares (ahí tenemos github copilot). En mi experiencia personal esto no deja de ser un autocompletado supervitaminado y mineralizado, pero es cierto que viene bien.
- Generación de documentación técnica (al estilo rdoc, javadoc, yard…). Sería la bomba, por ejemplo, generar la documentación en nuestro CI o, incluso mejor, directamente en nuestro IDE de forma automática.
- Entender código obtuso ininteligible para un humano medio, como pedirle que te explique expresiones
regularesreguleras - Crear código obtuso ininteligible para el humano medio, como pedirle que te genere una expresión regulera
- Nombrar cosas
- Como sustituto (o fase previa) a stackoverflow
- Como patito de goma (aka: “rubber duck debugging”){: .external-link target=”_blank”}
Y seguramente muchas más que no nombro aquí.
Mis conclusiones
Hoy todavía es pronto para sustituir el trabajo concreto de programación, pero el momento llegará. No sé si en un año, en cinco, o en diez. Y cuando llegue el momento habremos conseguido quitarnos de en medio la necesidad de tener que escribir código mantenible (al menos en una grandísima parte de nuestro día a día).
El desarrollador del futuro no tan lejano programará menos y dedicará más tiempo a especificar requisitos más o menos formales…
…o quizá no, quién sabe.