Lenguajes de programación. Definición y evolución (A3C34A1D04)

Lenguajes de programación. Definición y evolución

Los circuitos que componen los ordenadores trabajan con dos niveles de tensión. Son circuitos digitales, y estos dos niveles se asocian con los números 0 y 1. ¿Te resulta familiar ahora el término sistema binario? Las acciones que puede realizar un dispositivo informático se representarán a través de un conjunto de secuencias de 0 y 1.

Si antes hemos definido un programa como “el conjunto de instrucciones que contienen la funcionalidad deseada para la aplicación que se está desarrollando”, la recreación de ese programa en la memoria principal de un ordenador consistirá en la traducción de ese conjunto de instrucciones en secuencias de 0 y 1. A este sistema de códigos, directamente interpretable por la máquina, se le denomina lenguaje máquina.

Cada máquina tiene su propio lenguaje máquina con el que se puede programar. Este lenguaje es específico para la arquitectura interna de dicha máquina. En otras palabras, una máquina solo puede reconocer estas instrucciones o códigos de operaciones programada para ella. Todos los lenguajes máquina disponen de un conjunto de instrucciones similares: operaciones simples, para, por ejemplo, copiar información, operaciones aritméticas, operaciones lógicas, que manejan valores booleanos (verdadero y falso), y operaciones de entrada/salida, asociadas a las conexiones de la máquina con respecto al exterior.

Los programas en lenguaje máquina se ejecutan muy eficientemente, ya que se redactan específicamente para los circuitos que los han de interpretar y ejecutar. Este código es directamente interpretable por la CPU y no requiere de transformaciones previas para ser ejecutado. Sin embargo, la programación en lenguaje máquina es un trabajo difícil y extremadamente engorroso para el programador, siendo necesario que este conozca la arquitectura física de la máquina con un gran nivel de detalle.

Saber más

La programación en lenguaje máquina, en palabras de John Backus, era un arte oscuro, una materia arcana, solo al alcance de unos pocos que comenzaron a considerarse como miembros de una clase sacerdotal guardiana de ciertas habilidades y misterios demasiado complejos para los mortales normales, que se oponían a ningún cambio revolucionario que pudiese hacer la programación tan simple que cualquiera pudiera realizarla.

Precisamente, esta dificultad para programar fue lo que propició el objetivo de “democratizar la tarea de programar los ordenadores”, reduciendo el periodo de formación de los programadores y facilitando la tarea de programar máquinas. Se pretendía, así, incrementar la distancia entre los programas y el frío acero de la máquina para, al mismo tiempo, reducirla entre el código y los programadores. Para ello, sería imprescindible, como discutiremos más adelante, establecer un nivel de independencia entre el programa y la arquitectura en la que este se ejecutará.

Uno de los primeros avances significativos en esta dirección fue el uso de una notación simbólica o mnemónica, empleada para representar cada instrucción o código de operación de la máquina. Estas claves mnemotécnicas eran más fáciles de recordar que los códigos numéricos, pero, sin embargo, requerían que, una vez establecida la secuencia de instrucciones en mnemónico que solucionaban el problema, fueran traducidas a lenguaje máquina. A este lenguaje se le denominó lenguaje ensamblador.

El siguiente listado de código muestra un ejemplo de suma de dos números en código ensamblador para una arquitectura 8086, almacenados en las direcciones de memoria 4000 y 4002. El resultado  se almacena en las direcciones 5000 y 5002. El objetivo de mostrar este ejemplo es ilustrar el salto que existe entre llevar a cabo la programación en lenguaje máquina, directamente a través de ceros y unos, y la programación mediante una notación con un nivel semántico más elevado.

Listado código

Sin embargo, y al existir una correspondencia estrecha, generalmente uno a uno, entre las claves del lenguaje ensamblador y los códigos de las operaciones de las máquinas, la programación continúa estando próxima a la máquina y sigue siendo un proceso minucioso y complicado. En este contexto, se hace necesaria la creación de un lenguaje lo más cercano posible al programador que permita expresar las distintas acciones a realizar por la máquina. Aquí aparece el concepto de lenguaje de programación de alto nivel.

Los lenguajes de programación de alto nivel suelen asociarse a la noción de abstracción. En otras palabras, cuando usas un lenguaje de este tipo te puedes centrar en crear un programa sin preocuparte de los detalles de la máquina que lo ejecutará. La principal ventaja de este enfoque es que la programación se simplifica y se hace más entendible, en parte porque las sentencias de programación se parecen más al lenguaje humano de lo que ocurriría con un lenguaje de programación de bajo nivel, o incluso con respecto al lenguaje ensamblador. Como abordaremos más adelante, el uso de un lenguaje de alto nivel implica la necesidad de herramientas que traduzcan sus sentencias a lenguaje máquina.

Finalmente, y como puedes imaginar, en la actualidad no existe un único lenguaje de programación de alto nivel. Por el contrario, existe toda una variedad de lenguajes que varían en función de su objetivo de diseño y de sus características. Algunos de los más populares en los últimos años, o incluso décadas, son C, Java, Python o JavaScript. La figura 1 muestra los lenguajes de programación de alto nivel más populares desde 2002.

Índice TIOBE, en el que se muestra la evolución de los lenguajes de alto nivel más populares. Fecha de octubre de 2022

Figura 1. Índice TIOBE, en el que se muestra la evolución de los lenguajes de alto nivel más populares. Fecha de octubre de 2022.