Lenguajes
Lenguajes de programación¶
Aunque seamos expertos en lenguaje máquina, trabajar esta forma es inviable. Además de resultar tremendamente farragoso en el caso de programas con cientos de instrucciones, la probabilidad de cometer errores es muy alta, dado que es fácil equivocarse con los códigos.
Para facilitar la labor, en la prehistoria de la informática se inventaron mecanismos mediante los cuales, a partir de un texto escrito de acuerdo a una sintaxis “más humana”, se procedía a hacer una traducción para obtener el archivo ejecutable.
De esta forma, cuando estemos haciendo cualquier desarrollo, tendremos al menos dos archivos, uno de texto llamado fichero fuente (source file) , y el ejecutable en lenguaje máquina. Al proceso de conversión se le llama compilar el programa.
La sintaxis utilizada se denomina lenguaje de programación. Consiste en texto, pero no se trata de escritura libre. Cada lenguaje impone unas reglas de sintaxis y el uso de determinadas palabras clave (keywords).
El primer lenguaje de la historia fue el assembler, donde se sustituye cada código por una abreviatura que nos recuerde lo que hace. El ejemplo anterior podría ser algo así como:
global _start
section .text
_start: mov rax, 1 ; número de llamada para escribir en dispositivo
mov rdi, 1 ; 1 es la consola
mov rsi, mensaje ; dirección del texto a mostrar
mov rdx, 12 ; número de bytes
syscall ; llama al sistema
mov rax, 60 ; número de llamada para salir de programa
xor rdi, rdi ; código 0 de salida
syscall ; llama al sistema
section .data
mensaje: db "Hola, Mundo", 10 ; texto con salto de línea
Cada línea de texto es una instrucción, y a la derecha, tras el punto y coma, podemos poner texto libre, que será ignorado al compilar. A esto se le llama “comentarios”, y sirve para facilitar las cosas a quien necesite examinar el programa.
Lenguajes de alto nivel¶
Escribir los programas así es más factible que hacerlo en lenguaje máquina, pero sigue siendo poco productivo. A veces, para cada tarea se necesitan varias instrucciones. En el ejemplo anterior hay dos operaciones a realizar:
-
mostrar texto:
mov rax, 1 mov rdi, 1 mov rsi, mensaje mov rdx, 12 syscall
-
finalizar programa:
mov rax, 60 xor rdi, rdi syscall
Para mejorar la productividad, se inventaron los lenguajes “de alto nivel”, así llamados porque evitamos sumergirnos en las interioridades de la máquina. La idea es que nos limitemos a expresar lo que queremos hacer, dejando que los detalles los resuelva el compilador al generar el ejecutable final. En el ejemplo anterior, el texto del archivo fuente podría ser algo así como:
display "Hola, Mundo"
exit program
Tras crear este archivo con un editor de textos, lo traducimos a lenguaje máquina con el compilador. El archivo fuente contiene sentencias, que al compilarse, se convertirán en instrucciones ejecutables.
Además de facilitar la lectura y escritura del programa, los lenguajes de alto nivel proporcionan una capa de abstracción, haciendo que nos desentendamos de los detalles internos del ordenador y nos centremos en la lógica del algoritmo a desarrollar. Esto reduce tiempo y costes de desarrollo y evita errores de programación.
Nota
En el caso particular del lenguaje assembler, la operación de convertir de texto a lenguaje máquina se denomina ensamblar en lugar de compilar.
Portabilidad¶
Ya hemos visto que los programas de diferentes sistemas operativos son incompatibles entre ellos, porque el lenguaje máquina difiere. Ahora bien, si utilizamos un lenguaje de programación de alto nivel, podemos lograr un alto grado de portabilidad.
En la medida que la sintaxis sea común a todas las plataformas, diremos que los programas son “portables”, y tomando un único archivo fuente, bastará con traducirlo a los correspondientes lenguajes máquina, obteniendo versiones para cada sistema operativo.
Esta es otra ventaja de los lenguajes de alto nivel sobre el assembler, que no es portable en absoluto. Cada plataforma tiene su propio lenguaje assembler.
Lenguajes más populares¶
La irrupción de los lenguajes de alto nivel, allá por la década de 1950, fue un avance importante en el mundo de los desarrollos informáticos. Una primera experiencia fue el IBM Mathematical Formula Translating System, una sintaxis concebida por la compañía IBM para que los matemáticos escribiesen sus fórmulas, y eso se pudiera compilar convirtiéndose en programas de cálculo. Al final se consolidó como lenguaje de programación para científicos, con el nombre abreviado de FORTRAN.
La entrada de las computadoras en el mundo de los negocios dió lugar al lenguaje COBOL, creado en 1959 por una comisión de representantes de varios fabricantes.
En 1964, la universidad de Dartmouth inventó el lenguaje BASIC, pensado para que los estudiantes se familiarizaran con el mundo de la programación. Microsoft lo convirtió posteriormente en una especie de “seña de identidad”, con su Visual BASIC, muy popular a finales de los noventa.
Pascal fue concebido hacia 1970 por un profesor universitario suizo. Apple y Borland lo popularizaron, pero la competencia con Microsoft lo dejó bastante relegado tras el cambio de siglo.
Como alternativa a todos estos lenguajes pensados para usuarios, Bell Laboratories, que por aquella época era subsidiaria de la multinacional AT&T, creó en 1972 el lenguaje C, ideado para profesionales de la informática y bastante más técnico. En la década de los ochenta presentaron una versión más evolucionada, C++, que es muy utilizada en la creación de sistemas operativos y algoritmos profesionales, aunque muchos usuarios lo consideren bastante complejo y buscan otras alternativas.
A finales de siglo se puso de moda Java, un lenguaje concebido por Sun Microsystems (posteriormente absorbida por Oracle), con el propósito de independizar los programas de la plataforma, haciendo que sean portables. Microsoft ideó su propia propuesta en la misma dirección, y creó el lenguaje C#.
El surgimiento de las páginas web en 1993 también generó nuevas necesidades. JavaScript es el lenguaje por excelencia en el diseño de páginas.
Python, por su parte, surgió en 1995 con el propósito de crear una herramienta fácil de usar, productiva, y orientada a los profesionales.
En 2009 Google presentó una alternativa al lenguaje C, denominada Go.
¿Cuantos lenguajes de programación existen actualmente? Miles. Las iniciativas para lograr la mejor herramienta se han multiplicado exponencialmente desde el ámbito universitario, las empresas con intereses comerciales, como Microsoft, IBM o Apple, e incluso desde proyectos personales. Algunos lenguajes están orientados al desarrollo de tareas específicas, mientras que otros están considerados de propósito general.
Podemos ver una lista de los lenguajes más relevantes en la wikipedia.
¿Cuales son los más utilizados? Evidentemente no hay una contabilidad mundial que nos indique cuantas personas utilizan cada lenguaje. Pero haciendo búsquedas en Internet, podemos hacer un análisis de popularidad basándonos en el “ruido” generado:
- ¿Que lenguajes tienen su entrada en la wikipedia?
- ¿Cuantos libros encontramos sobre cada lenguaje?
- ¿Cuales son aquellos sobre los que más se debate en la red? Véase por ejemplo StackOverflow, el popular foro de consulta de dudas sobre programación.
- Podemos hacer búsquedas en Google, vídeos en Youtube, y un largo etcétera.
¿Hay algún estudio al respecto? Varios. Uno de los más populares es el de la empresa consultora TIOBE, de publicación mensual. Otro informe similar que se publica periódicamente es el de RedMonk. También podemos consultar PyPL, PopularitY of Programming Language Index.
Código¶
El contenido de un programa en lenguaje máquina está formado por códigos. Esto se denomina de forma genérica “program code”. Cuando hablamos del “código”, nos estamos refiriendo a las instrucciones del programa.
El texto fuente se conoce también como “código fuente”. El resultado de la compilación, en lenguaje máquina, “código objeto”.
Existe una polémica que ha hecho correr ríos de tinta. Un fabricante de software, cuando distribuye sus programas en forma de archivos ejecutables, ¿debe facilitar también su código fuente? A esto se le llama política de código abierto y es algo que algunos programadores no ven con buenos ojos, dado que descubre sus secretos y facilita que otras personas modifiquen y recompilen el programa. Sin embargo, los defensores del “open source” ponen sobre la mesa el concepto de libertad para examinar y modificar los programas que hayamos adquirido.
Intérpretes¶
El uso de un lenguaje de programación implica utilizar dos herramientas de trabajo, un editor de textos para crear el archivo fuente, y un compilador, que lo traduce a lenguaje máquina y genera un archivo ejecutable adaptado a determinado sistema operativo. Sin embargo existe otra alternativa, que consiste en sustituir el compilador por un intérprete.
Un intérprete es un programa capaz de tomar el texto de un archivo fuente, hacer una compilación “al vuelo” y ejecutarlo directamente, sin dejar rastro en forma de archivo ejecutable.
El uso de intérpretes tiene sus ventajas:
- es más fácil de usar que un compilador. Simplemente, escribimos un programa y lo ejecutamos, sin pasar por la fase de compilación
- lo que se ejecuta es el texto fuente, por lo que el usuario puede ver las instrucciones del programa. Con esto estaríamos respetando la política open source.
Pero también tiene inconvenientes:
- expone las instrucciones del programa al examen de terceros
- permite que el programa sea modificado por los usuarios, lo que invalida la posible garantía que el programador pueda ofrecer sobre su trabajo
- los programas se ejecutan más lentamente, dado que hay una doble tarea de traducción/ejecución, aunque la potencia de los procesadores actuales hace que esto sea bastante tolerable.
Bytecode¶
Una alternativa intermedia entre el compilador y el intérprete es el uso de bytecode. Consiste en una especie de lenguaje máquina universal, independiente del sistema operativo. Necesitaremos tres herramientas:
- con un editor de textos creamos el/los archivos fuente
- con un compilador los traducimos a lenguaje máquina bytecode, obteniendo archivos ejecutables
- para ejecutar el programa necesitamos un intérprete especial, que traduzca al vuelo de bytecode a lenguaje máquina nativo de cada sistema operativo.
¿Que ventajas tiene este planteamiento? La traducción de bytecode a lenguaje máquina es menos pesada, lo que acelera la ejecución de programas. Además, ganamos en portabilidad, ya que el formato bytecode es independiente de la plataforma. Y finalmente, no exponemos el programa a posibles modificaciones hechas por el usuario. Y si queremos adoptar la política open source, siempre podemos distribuir los archivos fuente de forma complementaria.
Existen varios lenguajes de programación que utilizan bytecode, como es el caso de Java, C# o Python. Pero nótese que no son compatibles entre ellos. Cada lenguaje tiene su propio bytecode.
Otros lenguajes como C o C++ son compilados a lenguaje máquina nativo. El resultado es más eficiente en términos de ejecución, pero nos obliga a recompilar los programas y crear versiones para cada sistema operativo.