Nuestros cursos:

Nuestros cursos:

Programación

Evolución de los lenguajes de programación: la incesante búsqueda de una mejor comunicación humano-computadora

En las décadas de 1960 y 1970, los programadores, tal como hoy los concebimos, no existían realmente. La programación era una disciplina emergente. Las computadoras eran artefactos nuevos y complejos operados principalmente por ingenieros electrónicos, físicos y matemáticos a través de lenguaje máquina.

En la figura se ve un ejemplo de programa en lenguaje ensamblador del procesador Intel 8080 para sumar dos números almacenados en memoria y guardar el resultado.

Instrucciones para sumar dos números en Assembly, procesador Intel 8080 (Fuente: autor).

El programa carga el valor almacenado en la dirección 2000H en el registro A, copia el valor del registro A al registro B, carga el valor de la dirección 2001H en el registro A, suma el valor del registro B al registro A, almacena el resultado en la dirección de memoria 2002H y detiene la ejecución.

Este programa no es claro ni legible, salvo que todas las explicaciones se agregaran al margen de las instrucciones mediante comentarios. Los nombres de variables no eran descriptivos, las direcciones de memoria (2000H, 2001H, etc.) eran difíciles de retener, teniendo en cuenta que los programadores debían recordar qué valores estaban almacenados en qué registros [27], [28].

EL lenguaje Fortran, considerado uno de los primeros lenguajes de alto nivel, fue desarrollado en 1957 por un equipo liderado por John Backus en IBM, con el objetivo de facilitar la programación en aplicaciones científicas y de ingeniería [29]. A continuación, vemos el mismo programa escrito en Fortran.

Instrucciones para sumar dos números en Fortran (Fuente: autor).

Los nombres significativos de variables mejoran la legibilidad y se ocultan detalles en un mayor nivel de abstracción.

PASCAL, surgió en los años 70 con el objetivo de mejorar la enseñanza de la programación estructurada.

 

Instrucciones para sumar dos números en PASCAL (Fuente: autor).

El código en Pascal es aún más legible que el de Fortran, ya que introduce una sintaxis más estructurada y clara con bloques. Pascal fue diseñado para enseñar buenas prácticas de programación estructurada [30].

En la Figura 4 vemos el mismo programa de suma de dos números en Python.

Instrucciones para sumar dos números en Python (Fuente: autor).

Python representa la evolución natural de los lenguajes de programación, ofreciendo una sintaxis extremadamente simple y cercana al lenguaje humano.

Sin embargo, cuando los programas son más extensos y complejos, cualquier lenguaje de programación representa un desafío para un humano. Por ejemplo, un pequeño descuido, como olvidar una coma o un punto y coma, puede generar errores de ejecución, lo que resalta la necesidad de una atención meticulosa a los detalles en la escritura del código.

Es por esta razón que, a lo largo de las décadas, han surgido diversas iniciativas en la enseñanza de la programación, con el objetivo de reducir la carga cognitiva de los estudiantes y facilitar su transición de lenguajes de bajo nivel a lenguajes más abstractos y accesibles [31], [32].

Estas iniciativas incluyen desde la creación de lenguajes de programación más amigables hasta el desarrollo de entornos visuales de programación, como Scratch, que buscan hacer más intuitiva la comprensión de conceptos abstractos de programación sin la necesidad de preocuparse por los detalles sintácticos minuciosos [33].

El panorama local de enseñanza

En la segunda década del siglo XXI, se desarrollaron en todo el mundo iniciativas para introducir las CC como espacio curricular obligatorio en la escuela secundaria. Este proceso no se desarrolló de manera homogénea, ni a nivel internacional ni a nivel nacional.

La gran diversidad de recorridos incluye, por un lado, países avanzados que lograron rápidamente incluir los contenidos de CC en sus planes de estudio, y, por otro lado, países como Argentina, para los cuales este cambio continúa siendo un desafío.

A partir del 2015 el Consejo Federal de Educación, declaró de interés estratégico la enseñanza de programación en las escuelas. Sin embargo, según la Ley de Educación Nacional (Ley 26.206, en sus Disposiciones Generales de 2006), se estableció que cada jurisdicción podía, basándose en los lineamientos generales, adaptar esta estructura curricular a su propio contexto.

Como consecuencia, el diseño curricular de cada provincia es particular, pero, además, dentro de cada provincia, las instituciones tienen cierta libertad para decidir contenidos, y asignar prioridades y obligatoriedades al currículo computacional. Esto da como resultado una gran disparidad en la formación computacional que queda de manifiesto en el ingreso universitario.

Si bien la Resolución 263/15 del Consejo Federal de Educación de Argentina aprobó en el año 2018 los “Núcleos de Aprendizajes Prioritarios de Educación Digital, Programación y Robótica” [34] para todos los niveles educativos, los lineamientos, orientados a la inclusión social y a la participación ciudadana, son bastante generales como para que continúe la diversidad jurisdiccional.

Los núcleos básicos para la escuela secundaria incluyen “la aplicación de habilidades analíticas, de resolución de problemas y de diseño para desarrollar proyectos de robótica o programación física, de modo autónomo, crítico y responsable…”. Pero esta afirmación bastante general, no alcanza su cumplimiento en la práctica.

Investigaciones nacionales han mostrado que, los temas específicos de CC no han sido adoptados de manera homogénea. En su lugar, la mayoría de los espacios curriculares atienden más a la articulación de las TICs con otras áreas, es decir, como herramientas para otros espacios curriculares, en vez de contenidos propiamente de CC [35].

En la provincia de Santa Fe, se han impulsado diversas iniciativas educativas, como el desarrollo de una carrera de especialización docente en informática para el nivel primario. Sin embargo, en el nivel medio persiste la falta de una especialización docente específica que asegure la adecuada implementación de los contenidos informáticos.

En Rosario, algunos colegios preuniversitarios han integrado contenidos de informática a sus planes de estudio desde hace décadas, mucho antes de las iniciativas más recientes en esta área. A pesar de ello, el ciclo secundario —especialmente en su tramo orientado y en los espacios de transición hacia la Universidad— sigue siendo un ámbito desatendido en lo que respecta a la enseñanza de informática.

En este contexto, la enseñanza de informática ha sido frecuentemente delegada a docentes provenientes de otras disciplinas, como matemática o química, disciplinas formales, pero también áreas como ciencias de la comunicación. Estos profesores, en su mayoría, tienden a emplear la informática como una herramienta para el desarrollo de sus áreas de base, en lugar de promover el pensamiento computacional y la comprensión de conceptos fundamentales de las ciencias informáticas.

Esta situación se vio agravada por la eliminación de informática como espacio curricular obligatorio, lo que constituye una contradicción con los discursos que abogan por la promoción del pensamiento computacional.

Como consecuencia, en las instituciones públicas donde se opta por incluir informática, los docentes de esta asignatura reciben su salario de las cooperadoras escolares, y su contratación depende exclusivamente de la decisión de cada escuela. Esta falta de obligatoriedad y de respaldo institucional no solo precariza la enseñanza de informática, sino que también afecta la continuidad y calidad de los contenidos impartidos.

La desconexión entre el nivel medio y el ámbito universitario genera importantes desafíos para los estudiantes que eligen seguir carreras relacionadas con la informática.

En particular, las universidades tecnológicas se enfrentan a la necesidad de nivelar a los ingresantes, quienes llegan con un conocimiento previo altamente dispar. Este proceso de nivelación debe realizarse en un breve curso introductorio, generalmente dictado junto con otras asignaturas, lo que intensifica la carga académica y dificulta la consolidación de los aprendizajes necesarios para afrontar el nivel superior.

La irrupción de la inteligencia artificial generativa

Un cambio inesperado sacudió esta narrativa de la difícil tarea de aprender a programar. En el recuadro puede verse una instrucción a ChatGPT para realizar el mismo programa mencionado en la sección anterior para sumar dos números en Python.  

Instrucciones a ChatGPT para sumar dos números en Python (Fuente: autor).

En enero de 2024, durante la World Government Summit, el CEO de NVIDIA realizó una declaración que apunta a transformar el paradigma del aprendizaje de la programación. Según este ejecutivo, la misión de su empresa es desarrollar tecnología informática que elimine la necesidad de programar de forma tradicional. Afirmó que el lenguaje de programación actual, para la mayoría de los usuarios, es el lenguaje humano, gracias a los avances en inteligencia artificial (IA). Según su visión, cualquier persona puede considerarse ahora un programador, ya que la IA ha logrado, por primera vez, cerrar la brecha tecnológica entre expertos y usuarios comunes [36]. ‬‬‬‬‬‬‬‬

Esta afirmación, que plantea un futuro en el que las habilidades de programación como las conocemos podrían volverse obsoletas, ha generado debates profundos. ¿Qué significa este cambio para las carreras de informática y para el sistema educativo en general?

Mientras que algunos ven estas declaraciones como un llamado a la evolución del rol de los ingenieros y desarrolladores, otros temen que este anuncio trivialice las complejidades inherentes a la programación y sus fundamentos teóricos. Al mismo tiempo, muchos estudiantes y educadores se enfrentan a una creciente incertidumbre sobre el valor de las competencias que actualmente se consideran esenciales para el campo.

La paradoja es evidente: en un contexto donde se busca mejorar las tasas de aprobación en materias como Programación y fomentar su enseñanza desde edades tempranas, se plantea la idea de que esas habilidades podrían no ser necesarias en el futuro cercano. Esto pone a los sistemas educativos, y a los propios estudiantes, frente a un dilema sobre cómo adaptarse a esta transformación tecnológica sin perder de vista los pilares fundamentales de la disciplina.

La nueva visión parece contradecir los esfuerzos que, durante años, muchos países han invertido en promover la enseñanza de CC antes y durante el ingreso universitario. Se propone que herramientas como la ingeniería de prompts y el análisis de datos sean las nuevas competencias clave. Sin embargo, esto no debe interpretarse como el fin de la carrera de ingeniería del software, sino como una transformación: la desaparición de tareas de bajo nivel en la programación.

Declaraciones como las del CEO de NVIDIA han llevado a algunos a pensar que, con el avance de la IAG, la carrera misma pierde sentido. Tecnologías como GitHub Copilot o Devin, capaces de codificar, depurar y realizar pruebas de manera autónoma, refuerzan esta percepción.

Esto ha generado inquietud entre los estudiantes que comienzan carreras en CC, quienes se preguntan si tendrán oportunidades laborales en el futuro, si su carrera seguirá siendo relevante y si vale la pena el esfuerzo de aprender disciplinas tan complejas. Por otro lado, aquellos que han intentado aprender a programar sin éxito tienden, sesgadamente, a validar la idea de que no es necesario adquirir estas habilidades.

Sin embargo, los expertos en el campo manifiestan cierto escepticismo sobre la capacidad real de la IA para reemplazar completamente el trabajo de los ingenieros, particularmente en lo que respecta a su interacción con los usuarios. Este ámbito, históricamente identificado como uno de los principales puntos de fricción en el desarrollo de sistemas, sigue siendo un desafío que la IA aún no ha logrado superar de manera definitiva.

Integración de asistentes de programación en la empresa

El uso de herramientas de asistencia basada en IA ha transformado sustancialmente la naturaleza del desarrollo de software.

En muchas empresas [37] han adoptado de manera extensiva GitHub Copilot, un asistente de codificación integrado en el entorno de desarrollo (IDE) que utiliza IA para sugerir y autocompletar funciones, bloques de lógica e incluso fragmentos completos de código mientras el programador escribe. Un estudio de GitHub muestra que el 92% de los desarrolladores en EEUU ya están usando Copilot [38].

Este asistente ha demostrado ser indispensable para el proceso de programación. Su capacidad para predecir el siguiente fragmento de código que se desea escribir mejora notablemente la productividad, permitiendo que tareas que antes requerían búsquedas externas, como encontrar funciones en bibliotecas o adaptaciones de respuestas de plataformas como Stack Overflow, se realicen de manera instantánea y eficiente.

La integración de Copilot ha incrementado la productividad, hasta el punto de que se considera una herramienta imprescindible. Por ejemplo, en la empresa Fixie, se estimó una reducción de la eficiencia entre un 30% y un 40% si se dejara de utilizar Copilot [39].

Contrario a la percepción de algunos que consideran a Copilot como una herramienta superficial, su impacto en la forma en que se programa es profundo y significativo. Copilot no solo sugiere funciones y métodos basados en un conjunto de datos general, sino que es capaz de extraer contexto directamente desde la base de código en la que el programador está trabajando, adaptándose al proyecto específico. Un ejemplo concreto de su efectividad se encuentra en su capacidad para generar pruebas unitarias. Mientras se desarrollan estas pruebas, Copilot es capaz de anticipar la siguiente prueba necesaria y generar automáticamente el código correspondiente, lo que acelera enormemente el proceso de desarrollo lo que reduce la carga cognitiva del programador.

Integración de asistentes en la educación

Sin lugar a duda, los Modelos de Lenguaje de Gran Escala (LLM, por sus siglas en inglés) tienen implicaciones significativas para la educación en general, y la enseñanza de la programación no está exenta de este impacto [40].

Aunque estos modelos no fueron diseñados inicialmente con fines educativos, su adopción presenta un desafío y una oportunidad para la transformación de los métodos pedagógicos en programación.

Actualmente, el objetivo de diversos educadores e investigadores es redefinir la enseñanza de la programación introductoria, con el propósito de desarrollar nuevas estrategias que equipen a los estudiantes con las habilidades necesarias para tener éxito en un entorno en el que los LLM juegan un papel central en el desarrollo de software [41], [42]. La visión de estos educadores busca no solo enseñar a programar de manera tradicional, sino también capacitar a los futuros programadores para que trabajen eficazmente en colaboración con estas herramientas avanzadas, aprovechando su capacidad para optimizar y facilitar el proceso de desarrollo de software.

El artículo escrito por Sam Lau y Philip J. Guo, explora las perspectivas de los instructores universitarios de programación introductoria frente al creciente uso de herramientas de generación y explicación de código basadas en IA por parte de los estudiantes [43]. Mediante entrevistas a 20 instructores de programación de nivel introductorio en nueve países, los autores identificaron diversas estrategias que los educadores planean implementar para adaptarse a esta nueva realidad.

A corto plazo, muchos instructores consideran medidas inmediatas para desalentar el uso indebido de estas herramientas y prevenir trampas asistidas por IA. A largo plazo, las opiniones varían: algunos proponen prohibir el uso de estas herramientas en el aula para mantener el enfoque en los fundamentos de la programación, mientras que otros abogan por integrarlas en los cursos para preparar a los estudiantes para su uso en entornos profesionales futuros.

Los argumentos principales a favor de adoptar estas herramientas son preparar a los estudiantes para futuros empleos y poder enseñarles temas más avanzados desde el principio. Estos instructores están entusiasmados con el uso de la IA para brindar ayuda personalizada a los estudiantes.

Un estudio experimental publicado en Github [44] se propuso medir la diferencia entre dos grupos de programadores novatos, uno utilizaba Copilot y el otro no. El grupo que utilizaba Copilot obtuvo una ventaja del 56% en la productividad con respecto al otro grupo. Si bien está clara la ventaja en productividad, la pregunta de fondo es qué incidencia tiene en el aprendizaje. ¿Se aprende más sin Copilot?

La investigación de Priyan Vaithilingam y su equipo [45], presentó un estudio de usuarios con 24 participantes para evaluar cómo los programadores utilizan y perciben herramientas de generación de código basadas en LLM, como GitHub Copilot. Se compararon dos grupos donde cada participante realizaba dos tareas en Python, una con Copilot y otra sin Copilot (usando sólo IntelliSense de Visual Studio Code). En este caso, no se observaron diferencias significativas entre las condiciones en términos de tasa de éxito o tiempo de ejecución. Sin embargo, la mayoría de los participantes manifestaron una preferencia por el uso de Copilot, principalmente debido a que les proporciona un punto de partida útil para la escritura de código ya que les brinda fragmentos de código iniciales que sirven como base.

Sin embargo, otro hallazgo clave es que los estudiantes experimentaron dificultades en comprensión y depuración. Aproximadamente la mitad de los participantes tuvieron problemas al corregir el código generado por Copilot, lo que sugiere que la supervisión y la capacidad de depuración continúan siendo habilidades fundamentales en la enseñanza de la programación.

En el estudio de Kazemitabaar [46], los participantes eran estudiantes principiantes sin experiencia previa en programación en Python. Inicialmente, se les enseñaron conceptos fundamentales de programación y pensamiento computacional. Posteriormente, se les solicitó completar un conjunto de 45 tareas en Python, estructuradas en dos fases: la primera consistió en la escritura de código desde cero, mientras que la segunda implicó la modificación de código existente para ajustarlo a nuevos requerimientos.

Los participantes se dividieron en dos grupos: uno de ellos tuvo acceso a Codex durante la fase de creación de código desde cero, mientras que el otro grupo no contó con dicha asistencia. En la fase de modificación del código, ninguno de los grupos tuvo acceso a la herramienta de IA, por lo que todos los participantes debieron realizar los ajustes de manera autónoma.

Respecto a los resultados obtenidos en la fase de creación de código, los participantes que utilizaron Codex mostraron un desempeño superior, con diferencias tanto estadística como prácticamente significativas. Este hallazgo resulta coherente con estudios previos que han evidenciado la alta efectividad de los LLM en la resolución de problemas introductorios de programación. Sin embargo, una cuestión relevante era determinar si esta ventaja inicial persistiría en la fase de modificación del código, una vez que los participantes del grupo experimental ya no contaran con la asistencia de Codex. En otras palabras, si haber trabajado con Codex representaba una ventaja o una desventaja en relación con el aprendizaje. La hipótesis de base era que el grupo sin acceso a Codex aprendería más y luego sería más efectivo en la fase sin ayuda.

Contrariando dicha hipótesis, los resultados indicaron que el grupo experimental que utilizó Codex mantuvo un rendimiento superior, aunque sin alcanzar significancia estadística. Además, los participantes de este grupo reportaron menores niveles de ansiedad y frustración en comparación con aquellos que no contaron con asistencia de IA, lo que sugiere un impacto positivo en la percepción del proceso de aprendizaje.

Estos efectos se mantuvieron en una prueba de retención aplicada una semana después, en la que el grupo experimental continuó mostrando un mejor desempeño en ambas fases de la tarea, a pesar de no contar con acceso a Codex en ese momento.

Una posible explicación de estos hallazgos radica en la forma en que los participantes del grupo experimental interactuaban con el código desde el inicio, explorándolo y ejecutándolo de manera inmediata, en lugar de enfrentarse primero a dificultades relacionadas con errores de sintaxis. Desde el punto de vista psicológico del aprendizaje, no siempre la resolución autónoma de un problema conduce a un mayor aprendizaje de la solución. La comparación de casos puede ser más efectiva, y estas herramientas proveen ejemplos con facilidad.

Adicionalmente, los investigadores observaron que los participantes del grupo Codex mostraban una mayor tendencia a realizar pruebas sobre su código y a descomponer funciones de gran tamaño en unidades más pequeñas, comportamientos que suelen ser menos frecuentes en estudiantes de nivel introductorio. Esto sugiere que la presencia de una herramienta de IA podría fomentar de manera natural buenas prácticas de programación, como la validación y modularización del código.

Estos resultados proporcionan evidencia empírica sobre el impacto del uso de asistentes de IA en la enseñanza de la programación. La integración de herramientas como Copilot y Codex en los cursos introductorios de CC (CS1) representa un cambio en la forma en que los estudiantes abordan el aprendizaje de la programación. No obstante, estos avances también plantean nuevas preguntas y desafíos en la educación en informática.

En este contexto, resulta fundamental reevaluar los métodos de enseñanza y adaptar los planes de estudio para aprovechar las ventajas de estas tecnologías, al tiempo que se fortalecen habilidades esenciales como el razonamiento algorítmico y la capacidad de depuración de código.

Reevaluar el lugar de la programación

Tendemos a confiar más en las formulaciones matemáticas rigurosas para explicar los procesos reales que en las explicaciones pragmáticas. Sin embargo, esta preferencia por la abstracción tiene un costo: cuanto más nos alejamos del contexto práctico, mayor es el riesgo de perder de vista la aplicación real. Las abstracciones son herramientas poderosas, pero deben equilibrarse con una comprensión profunda de la realidad que buscan modelar.

En las ciencias de la computación se valora más la lógica formal (que utilizan los ordenadores) que la lógica informal (argumentación en contextos reales). Tradicionalmente, se ha dado un gran peso a la lógica matemática y a la formalización rigurosa de problemas, en detrimento de la lógica informal y la argumentación. Si bien la lógica formal es fundamental para la verificación y construcción de algoritmos correctos, la lógica informal es clave en la interpretación y aplicación de estos modelos en contextos reales y traducir problemas del mundo real en especificaciones computacionales.

La argumentación y el razonamiento práctico podrían ser en este momento las disciplinas que más importancia tengan en la formación de los nuevos ingresantes a ingenierías del software.

Algo análogo sucede con la programación. Durante décadas, la programación ha sido considerada una habilidad altamente especializada y difícil de dominar, en gran parte debido a la naturaleza artificial de los lenguajes de programación.

A diferencia del lenguaje natural, que los seres humanos adquieren de manera intuitiva a lo largo de su desarrollo cognitivo, los lenguajes de programación requieren una estructura sintáctica y semántica precisa, lo que ha contribuido a su percepción como una disciplina altamente técnica y exclusiva. Sin embargo, con el avance de las herramientas de inteligencia artificial y los entornos de desarrollo cada vez más intuitivos, la programación ya no es la barrera infranqueable que solía ser.

En este contexto, es pertinente cuestionar si la sobrevaloración de la programación como una habilidad puramente técnica ha llevado a desestimar otros aspectos esenciales del desarrollo de software, como el razonamiento lógico aplicado y la comprensión de los problemas a resolver.

En el desarrollo de software, la capacidad de comprender los requisitos reales de un sistema es tan crucial como la habilidad de codificarlo. Un enfoque excesivamente centrado en la programación como actividad técnica puede llevar a soluciones ineficientes o desconectadas de las necesidades del usuario.

La interpretación de requerimientos, la comunicación con usuarios y la traducción de necesidades en modelos computacionales requieren habilidades de argumentación y razonamiento informal. Por lo tanto, si bien la lógica formal sigue siendo una herramienta fundamental en la computación, su aplicación efectiva depende de la capacidad del programador para contextualizarla dentro de un marco más amplio de razonamiento y toma de decisiones.

En este sentido, la evolución de la disciplina de la informática debería enfatizar no solo la enseñanza de estructuras sintácticas y formales, sino también la formación en habilidades de razonamiento informal, comunicación efectiva y modelado conceptual.

La creciente automatización de la programación mediante herramientas basadas en inteligencia artificial refuerza aún más esta necesidad: si el acto de escribir código deja de ser la tarea central del programador, su rol se desplazará hacia la capacidad de definir problemas, diseñar soluciones y evaluar la coherencia de los sistemas con el entorno en el que operan. En consecuencia, la educación en informática debe revalorizar la argumentación y la lógica informal como competencias esenciales para la resolución efectiva de problemas computacionales.

Lo que distingue a la ingeniería del software de otras ingenierías

En primer lugar, cabe recordar que gran parte de los estudiantes de ingeniería del software no aspiran a ser sólo programadores, sino desarrolladores, posicionándose en niveles superiores de abstracción en esta cadena de desarrollo. La pregunta es, en qué nivel de abstracción y demanda cognitiva se sitúan las próximas expectativas laborales, si la IAG no puede interactuar directamente con los usuarios y si esa comunicación es clave.

El problema se centra en dos cuestiones esenciales:

  1. La capacidad de los usuarios para explicitar el problema con claridad, ya que suelen tener dificultades para describir de forma precisa y completa lo que necesitan o los problemas que enfrentan, lo cual complica que una IA interprete correctamente sus requerimientos
  2. La capacidad de los ingenieros y, especialmente, los estudiantes novatos, para interpretar con precisión el problema, incluso aunque no hubiera necesidad de programarlo en un lenguaje particular.

Ambos lados del proceso, tanto el de los usuarios como el de los diseñadores y estudiantes, comparten una dificultad común: la comprensión y comunicación efectiva del problema.

Esta brecha en la explicitación y el entendimiento sigue siendo uno de los desafíos más críticos en el desarrollo de sistemas. No se trata únicamente de una cuestión técnica, sino de competencias lingüísticas, expresivas y comunicacionales, esenciales para transmitir y comprender con claridad las necesidades y problemas que deben resolverse.

Aquí es donde cobran relevancia las habilidades que en contextos tecnológicos son denominadas “blandas”, y que han sido fundamentales en la ingeniería del software de una manera única, diferenciando esta disciplina de otras especialidades de la ingeniería.

La divergencia entre disciplinas con respecto a qué nivel de importancia le atribuyen al lenguaje y la comunicación tiene una base en la naturaleza del trabajo, los resultados esperados y los procesos de creación. En otras ingenierías, como por ejemplo la ingeniería mecánica o electrónica, los productos suelen ser tangibles y concretos, como piezas mecánicas y circuitos eléctricos. Las especificaciones técnicas suelen estar claramente definidas mediante estándares, códigos de diseño, planos y modelos matemáticos.

Estos estándares y lenguajes técnicos (como diagramas de CAD, esquemáticos o ecuaciones) son universales y menos interpretativos. La comunicación sigue siendo importante, pero la interpretación subjetiva del lenguaje natural es menos crítica porque los detalles técnicos ya están formalizados en especificaciones claras.

El software, en cambio, es un producto intangible que depende completamente de los requisitos definidos en lenguaje natural, traducidos después a código. Los usuarios finales suelen ser no técnicos, lo que significa que sus necesidades deben interpretarse y transformarse en soluciones digitales. El software, al no estar limitado por reglas físicas como una pieza mecánica o electrónica, es más propenso a interpretaciones variadas. La ambigüedad en los requisitos iniciales puede resultar en un producto que no cumple con las expectativas del usuario.

Por otra parte, existen diferencias en la naturaleza del diseño. En la mayoría de las ingenierías, los procesos de diseño suelen seguir un flujo más lineal, por ejemplo:

1. definición del problema,

2. diseño técnico (con cálculos y planos),

3. fabricación y prueba del prototipo.

La retroalimentación del cliente es limitada porque los requisitos se derivan de especificaciones técnicas rígidas y estándares preexistentes. Gran parte del trabajo se realiza en términos de modelos matemáticos y físicos, donde el lenguaje técnico (como unidades, fórmulas y diagramas) es universal y objetivo.

En cambio, el desarrollo de software tiende a ser iterativo e incremental, por ejemplo:

1. se relevan los requisitos,

2. se desarrollan prototipos,

3. se prueban y se actualizan los requisitos (retroalimentación).

El éxito depende de la colaboración continua con los usuarios finales, especialmente porque los requisitos cambian con frecuencia. Debido a la ausencia de estándares universales, las interacciones humanas y las habilidades de comunicación se vuelven críticas para garantizar que todos los involucrados compartan la misma visión.

Con respecto a la complejidad de los requisitos del cliente, en las ingenierías tradicionales, los clientes suelen proporcionar requisitos técnicos más claros, como: “diseñar un engranaje que soporte una carga de 5000 N”, o “diseñar un circuito que regule una corriente de 10 A a 5 V”. Los parámetros son cuantificables y medibles, dejando menos espacio para la interpretación. Aquí, el lenguaje natural es secundario al lenguaje técnico.

En cambio, en el software, los requisitos suelen expresarse en términos generales o abstractos, como: “quiero que la aplicación sea fácil de usar”, o “necesitamos un sistema que automatice nuestros procesos”. Estos requisitos no son directamente cuantificables ni fáciles de medir, lo que introduce ambigüedad y subjetividad. Traducirlos a especificaciones técnicas implica diálogos constantes con los usuarios para aclarar su significado.

Con respecto al contexto humano y social, en las ingenierías tradicionales, el producto final está más desconectado del usuario final. Por ejemplo, un componente mecánico puede ser parte de una máquina que será usada por operadores, pero no requiere interacción directa con el usuario para diseñarlo. Un circuito electrónico puede ser parte de un dispositivo más grande, y su diseño no depende de la interacción con el cliente final.

Los ingenieros en estas disciplinas se centran más en cálculos, simulaciones y pruebas que en comprender subjetividades humanas.

En cambio, el software interactúa directamente con el usuario final, lo que lo hace intrínsecamente centrado en el usuario. Los usuarios tienen diferentes niveles de habilidades técnicas y necesidades específicas que los desarrolladores deben interpretar y satisfacer. Factores como la usabilidad, la experiencia del usuario y la adaptación a contextos culturales no se pueden resolver únicamente con habilidades técnicas: requieren una comunicación efectiva para comprender y empatizar con los usuarios.

Los riesgos asociados a problemas en la comunicación son requisitos mal definidos, funcionalidades innecesarias o irrelevantes, interfaces de usuario poco intuitivas. A menudo, estos problemas no se detectan hasta etapas avanzadas (o incluso después del lanzamiento), lo que resulta en proyectos fallidos o productos que no cumplen con las expectativas del cliente.

La ingeniería del software depende profundamente de la comunicación interpersonal y verbal. Esto hace que en el desarrollo de software la competencia lingüística, la capacidad de escucha activa y la empatía, sean tan importantes como las habilidades técnicas.

Por qué todavía tiene sentido aprender algo sobre programación

En el desarrollo de software, uno de los mayores desafíos radica en comprender y definir lo que los usuarios realmente necesitan.

Los expertos han identificado repetidamente un obstáculo crítico: los usuarios a menudo no saben exactamente lo que quieren, no pueden expresarlo con claridad o cambian de idea respecto a sus necesidades. Este fenómeno destaca la importancia de la explicitación verbal como una herramienta clave para lograr un entendimiento mutuo entre desarrolladores y usuarios.

El problema de las especificaciones

Una especificación clara y precisa es esencial para resolver cualquier problema de software. Según Polya [47], “un problema bien planteado está parcialmente resuelto”. En otras palabras, cuando logramos describir un problema sin ambigüedades, gran parte del camino hacia su solución ya está recorrido.

Esto se vuelve particularmente importante en el contexto actual, donde las herramientas de IA han reducido significativamente la distancia entre los usuarios y los lenguajes de programación.

Sin embargo, aunque la IA puede procesar lenguaje humano de manera impresionante, los usuarios no son naturalmente generadores de especificaciones completas y libres de ambigüedad. Las descripciones dadas por los usuarios suelen ser vagas, subjetivas o poco estructuradas. Esto plantea una pregunta fundamental: ¿cómo garantizar que las especificaciones sean completas, precisas y procesables por un ordenador?

¿Qué debe dontener una buena especificación?

Una buena especificación debe cumplir con ciertos criterios para garantizar que pueda ser interpretada correctamente, tanto por humanos como por máquinas. Estas características incluyen:

  • Claridad: Debe evitar términos ambiguos o vagos que puedan interpretarse de diferentes maneras. Por ejemplo, en lugar de decir “El sistema debe ser fácil de usar”, describir qué significa “fácil de usar” (número de clics, tiempo de respuesta, diseño intuitivo).
  • Precisión: La especificación debe incluir detalles exactos y medibles. Por ejemplo: “El sistema debe procesar 100 transacciones por segundo con un tiempo de respuesta menor a 1 segundo.”
  • Integridad: Debe abarcar todos los aspectos del problema, incluyendo requisitos funcionales, no funcionales, restricciones y casos de excepción.
  • Consistencia: Evitar contradicciones entre diferentes partes de la especificación.
  • Abstracciones Procesables: Debe usar un lenguaje o formato que permita a los desarrolladores traducir los requerimientos en soluciones técnicas. Aquí es donde conceptos como pseudocódigo o diagramas de flujo resultan esenciales para transformar una idea en una estructura lógica que la IA o un programador pueda comprender.

Aunque las herramientas de IA han avanzado en interpretar el lenguaje natural, sigue existiendo una distancia entre lo que los usuarios expresan y lo que es necesario para desarrollar un software funcional. Por ejemplo, un usuario podría describir su necesidad como: “Quiero una aplicación que me ayude a organizar mi tiempo.” Sin embargo, esta descripción es demasiado amplia y ambigua. ¿Qué significa “organizar”? ¿Debe incluir un calendario? ¿Recordatorios? ¿Una lista de tareas? ¿Cómo deben interactuar estas funcionalidades entre sí?

Los prompts como nueva forma de especificación

Para llegar a obtener una respuesta útil de la IAG, por ejemplo, un programa que resuelva un problema se necesita en primer lugar la descripción exacta y desambiguada de ese problema. Esto implica capacidad atencional para leer y comprender un problema o, para interpretar un requerimiento de usuario que aún no ha sido formalizado por escrito.

Devin es una herramienta desarrollada por Cognition, diseñada para asistir en el desarrollo de software de manera autónoma [48]. Si seguimos atentamente las demostraciones de Devin en acción en el blog oficial de Cognition, donde se presentan ejemplos de sus capacidades, como la creación de aplicaciones interactivas y la depuración de código, podemos ver que el tipo de prompts que escriben los programadores demuestran diferentes niveles de complejidad y la necesidad de conocimientos de programación.

Si bien Devin está diseñado para manejar instrucciones en lenguaje natural y traducirlas en código funcional, redactar prompts efectivos aún requiere comprender conceptos de programación, lógica y restricciones. A continuación, se presentan algunos ejemplos extraídos y traducidos del sitio web:

Ejemplo 1. Prompt de Nivel Intermedio

Prompt:
“Crea una función en Python que reciba una lista de números como entrada y devuelva un diccionario donde las claves sean los números únicos y los valores sean las cantidades de veces que aparecen esos números. Asegúrate de que la función maneje casos límite, como una lista vacía o una entrada no válida.”

Conocimientos de programación para redactar el prompt:

  • Comprensión de diccionarios y bucles en Python.
  • Conciencia sobre casos límite y validación de entradas.
  • Lógica para calcular la frecuencia de los números.

Ejemplo 2. Prompt Avanzado con Dependencias

Prompt:
“Construye una aplicación web con Flask que incluya un endpoint /prime que acepte un número como parámetro de consulta y devuelva si el número es primo. Incluye un manejo básico de errores para entradas no numéricas.”

Conocimientos de programación para redactar el prompt:

  • Familiaridad con Flask para desarrollar aplicaciones web.
  • Conocimiento de métodos HTTP y parámetros de consulta.
  • Comprensión de algoritmos para verificar números primos y manejo de errores.

Ejemplo 3. Prompt Complejo con Interacciones Múltiples

Prompt:
“Escribe un programa en JavaScript que obtenga datos de una API pública (por ejemplo, JSONPlaceholder) y los muestre en una tabla paginada en una página web. La tabla debe incluir columnas para ‘Título’ y ‘Cuerpo’, con 10 filas por página. Agrega botones de navegación para la paginación.”

Conocimientos de programación para redactar el prompt:

  • Comprensión de promises[1] en JavaScript y el uso de la API fetch()[2].
  • Manipulación del DOM para renderizar tablas dinámicas.
  • Gestión del estado para la paginación (página actual, total de páginas).

Los ejemplos presentados ilustran cómo la redacción de prompts para generar código a través de herramientas de IA requiere no solo una comprensión de los requisitos del problema, sino también una familiaridad con los lenguajes de programación y las bibliotecas utilizadas.

Sin embargo, uno de los aspectos más cruciales es la capacidad para razonar sobre algoritmos, patrones de diseño e interacciones con el usuario. Al experimentar con herramientas como Devin, se puede cerrar la brecha entre las instrucciones en lenguaje natural y las implementaciones técnicas detalladas, aunque siempre será fundamental mantener una base sólida en programación.

Si pidiéramos a dos grupos —uno de estudiantes sin conocimientos de programación y otro de expertos— que utilicen IA para generar un programa basado en una descripción, los resultados probablemente serían muy diferentes. Los estudiantes sin experiencia en programación suelen generar prompts poco estructurados, utilizando lenguaje natural sin identificar conceptos clave o abstraer los elementos necesarios del problema. Por ejemplo, una solicitud como “crea una aplicación para organizar el tiempo” podría producir una respuesta genérica y posiblemente incorrecta por parte de la IA.

Esta diferencia de resultados se puede explicar a través de investigaciones en psicología cognitiva, particularmente los estudios de Michelene Chi [49] sobre expertos y novatos.

Chi ha demostrado que una de las principales diferencias entre novatos y expertos es la forma en que abordan los problemas. Los expertos, gracias a su experiencia acumulada, son capaces de identificar y organizar conceptos clave de manera más eficiente, lo que les permite generar soluciones más precisas y apropiadas desde el inicio. En cambio, los novatos, al carecer de esta experiencia, tienden a abordar los problemas de manera más superficial y desorganizada, sin identificar las abstracciones necesarias para formular un prompt eficaz.

Chi [49] señala que los novatos a menudo carecen de una comprensión profunda de las estructuras subyacentes de los problemas, lo que se refleja en su incapacidad para formular preguntas precisas o soluciones estructuradas.

Esto se debe a que los novatos todavía están en proceso de aprender a abstraer y descomponer los problemas en componentes manejables. En contraste, los expertos no solo tienen un conocimiento más profundo del dominio, sino que también son mejores para reconocer patrones y aplicar soluciones generales a problemas complejos.

En este contexto, la redacción de prompts adecuados se convierte en un ejercicio de abstracción y resolución de problemas. El entrenamiento inicial en programación, que enseña a los estudiantes a abstraer y descomponer problemas en partes más simples, es fundamental para que puedan estructurar correctamente sus prompts.

Según Chi, este entrenamiento permite a los estudiantes pasar de un enfoque superficial a un enfoque más profundo y organizado, lo que es crucial cuando se interactúa con herramientas de IA que generan código.

La necesidad de aprender programación y pseudocódigo

Como se explicó, aunque la IAG pueda ayudar en muchas tareas, los estudiantes aún deben aprender ciertos fundamentos de programación para ser capaces de comprender cómo estructurar problemas, ya que la programación enseña a descomponer problemas complejos en pasos lógicos y manejables.

Además, es necesario desarrollar especificaciones procesables, es decir, no sólo que estén redactadas en un lenguaje humano, sino que se tenga consciencia de que estas especificaciones se transformarán en procesos digitales. El aprendizaje de pseudocódigo permite estructurar ideas de forma que puedan ser entendidas tanto por humanos como por máquinas.

La inteligencia artificial está transformando la manera en que desarrollamos software, pero no elimina la necesidad de habilidades humanas. Al contrario, redefine el enfoque:

Los desarrolladores deben centrarse en las habilidades de alto nivel, como entender al usuario, estructurar problemas, crear especificaciones claras y validar los resultados. Las tareas rutinarias o repetitivas de bajo nivel están siendo asumidas por herramientas como GitHub Copilot, pero estas herramientas dependen de entradas bien diseñadas para producir resultados de calidad.

La explicitación verbal y la creación de especificaciones claras son más importantes que nunca en el desarrollo de software.

Aunque las herramientas de IA han cerrado la brecha entre usuarios y lenguajes de programación, siguen siendo necesarios expertos que transformen las necesidades imprecisas de los usuarios en descripciones procesables y libres de ambigüedades. Aprender programación y pseudocódigo sigue siendo esencial para formar a futuros desarrolladores que no solo dependan de la IA, sino que también sepan guiarla para producir soluciones efectivas.

La delegación de tareas y la capacidad de razonamiento humano

La delegación excesiva de tareas a la IA puede llevar a un debilitamiento de los procesos de pensamiento fundamentales, lo que plantea un desafío urgente: desarrollar estrategias para sostener y fortalecer los propios procesos cognitivos, “obligando a pensar” de manera activa y consciente.

Este desafío es especialmente relevante en el contexto de los intercambios humano-computadora, donde la dependencia de respuestas automáticas podría afectar la calidad de las interacciones cognitivas.

Algunas estrategias abordan este problema al centrarse en el tipo de herramientas utilizadas. Se puede promover el uso de herramientas y métodos que desaceleren la velocidad de la respuesta automática del usuario humano. Por ejemplo, emplear medios de baja velocidad, que implican una mayor manipulación motriz, como el tradicional lápiz y papel, al realizar notas en papel antes de escribir nuevos prompts o modificaciones al diseño digital, promueve una mayor participación de procesos de pensamiento humano.

De hecho, algunas investigaciones han demostrado que la escritura a mano favorece un mayor involucramiento de los procesos cognitivos en los intercambios humano-computadora, lo que resulta en una mejor retención de la información. Una de las investigaciones clave que respalda esta afirmación es el estudio realizado por la Universidad de Princeton y la Universidad de California en Los Ángeles [50] que comparó la retención de información entre estudiantes que tomaron notas a mano y aquellos que utilizaron computadoras.

Los resultados mostraron que los estudiantes que escribieron a mano retuvieron mejor la información, debido a que el proceso de escritura manual les permitió sintetizar y procesar la información de manera más profunda. Los estudiantes que utilizaron computadoras tendieron a transcribir la información de manera más directa y rápida, lo que resultó en una menor comprensión y retención.

Además, estudios como el realizado por la Universidad de Michigan [51] refuerzan esta idea al señalar que la escritura manual activa diferentes áreas cerebrales en comparación con el uso de dispositivos electrónicos. La escritura a mano fomenta un enfoque multisensorial y de atención más profunda, mientras que el uso de dispositivos electrónicos, con su velocidad de respuesta rápida, puede facilitar una menor participación cognitiva.

Estos estudios subrayan cómo la escritura a mano facilita un tipo de procesamiento cognitivo más profundo, lo cual es beneficioso no solo para la retención de información, sino también para la calidad general de los intercambios humano-computadora.

Por lo tanto, el uso de herramientas que desaceleren la respuesta automática, como la escritura a mano puede promover una mayor participación de los procesos de pensamiento humano, lo cual es esencial para mantener y fortalecer nuestras habilidades cognitivas

Hoy en día, las expectativas sobre la IAG están en constante crecimiento. Sin embargo, esta fascinación tecnológica puede llevar a que estudiantes (y docentes) subestimen la importancia de los propios procesos de razonamiento.

Una de las razones de este fenómeno es la naturaleza abstracta y poco evidente del pensamiento humano. Por ello, esta guía no solo ofrece ejercicios de programación, sino que también tiene como propósito hacer visibles esos procesos cognitivos y reflexivos, fortaleciendo las habilidades de razonamiento crítico de los estudiantes.

El objetivo para el estudiante no solo debería ser aprender a resolver problemas de programación, sino también poder desarrollar una capacidad de análisis y autoevaluación mediante la escritura explicativa.

En la era de la IA, comprender el “por qué” detrás del código que se escribe es tan importante como el código mismo. Esto convierte la escritura, el diseño de diagramas y la reflexión en herramientas esenciales para que los estudiantes actúen y mejoren sobre sus propios pensamientos.

Si bien los programas universitarios varían, la mayoría de las asignaturas iniciales en ingeniería o licenciaturas informáticas suelen dividirse en dos partes: una dedicada al aprendizaje de algoritmos en pseudocódigo y otra a la implementación de estos algoritmos en lenguajes de programación específicos (como C, Python, entre otros).

No obstante, esta metodología plantea un desafío significativo: obliga al estudiante a equilibrar dos procesos de aprendizaje complejos de forma simultánea. Por un lado, comprender las estructuras algorítmicas abstractas; por otro, familiarizarse con las reglas y sintaxis de un lenguaje de programación. Ambos objetivos son fundamentales, pero al abordarlos al mismo tiempo, puede resultar difícil para los estudiantes alcanzar un dominio profundo en cualquiera de los dos.

Es importante reconocer que los fundamentos algorítmicos actúan como un puente hacia el aprendizaje de nuevos lenguajes de programación. Análogamente al aprendizaje de idiomas, donde una base sólida en gramática facilita la adquisición de una segunda lengua, los conceptos de estructuras algorítmicas sirven como gramática para la programación. Sin esta base, los estudiantes podrían enfrentar un mayor desafío al tratar de dominar un lenguaje de programación, similar a lo que ocurre con el aprendizaje de una lengua extranjera sin una comprensión previa de la gramática de su idioma nativo.

La programación no es solo un acto técnico; es un ejercicio intelectual que transforma tanto el mundo como al programador. Con cada solución algorítmica planteada, los estudiantes no solo automatizan procesos del mundo real, sino que también moldean y enriquecen sus propias estructuras de pensamiento.

Este crecimiento intelectual es quizás el resultado más significativo que esta asignatura puede ofrecer a los futuros profesionales de la informática.


  1. Una promise (promesa) es un objeto que representa la eventual resolución o rechazo de una operación asincrónica. Es decir, una forma de manejar operaciones que no se completan de inmediato, como leer archivos, hacer peticiones a servidores, o esperar respuestas.
  2. API fetch(): La API fetch() es una función en JavaScript que se utiliza para hacer peticiones HTTP (por ejemplo, para obtener datos de un servidor).


Deja un comentario