1.5.-Lenguajes de programación
1.5. Lenguajes de programación¶
Idea principal
Un lenguaje de programación ofrece reglas para expresar instrucciones que una máquina puede procesar. Clasificarlo por su ejecución, su nivel de abstracción y sus paradigmas ayuda a elegir herramientas adecuadas, pero ninguna etiqueta decide por sí sola qué lenguaje es «mejor».
En los apartados anteriores has visto cómo el código fuente se transforma y qué traductores intervienen. Ahora toca mirar el punto de partida: los lenguajes con los que una persona desarrolladora expresa una solución. No se elige igual la tecnología para el firmware de un sensor, una aplicación web, un servicio empresarial o un análisis de datos.
El objetivo de este tema no es memorizar listas de lenguajes, sino clasificarlos, reconocer sus características y justificar una elección según el problema, el equipo y el entorno donde se ejecutará la aplicación.
Según la normativa del módulo Entornos de Desarrollo, este contenido contribuye al siguiente resultado de aprendizaje y criterio de evaluación:
| Código | Descripción |
|---|---|
| RA 1 | Reconoce los elementos y herramientas que intervienen en el desarrollo de un programa informático, analizando sus características y las fases en las que actúan hasta llegar a su puesta en funcionamiento. |
| CE 1.e | Se han clasificado los lenguajes de programación, identificando sus características. |
Qué deberías saber al terminar
Al acabar este apartado deberías poder:
- explicar qué son el léxico, la sintaxis y la semántica de un lenguaje;
- clasificar un lenguaje por su modo de ejecución, nivel de abstracción y paradigma;
- identificar datos, variables, operadores, instrucciones y comentarios en un programa;
- comparar las características de Python, Java, C y JavaScript;
- justificar una elección de lenguaje sin reducirla únicamente a la velocidad o la popularidad.
Mapa del tema
En este documento seguiremos esta secuencia:
- qué reglas componen un lenguaje;
- cómo se clasifican los lenguajes;
- qué elementos aparecen en la mayoría de programas;
- cómo comparar lenguajes habituales y tendencias;
- cómo tomar una decisión técnica razonada.
1. Qué es un lenguaje de programación¶
Un lenguaje de programación es un sistema formal que permite escribir instrucciones para que un ordenador las procese. Para que un programa sea válido no basta con que «parezca» código: debe respetar las reglas definidas por el lenguaje y, además, expresar una operación con sentido.
Las tres capas básicas
- El léxico define los símbolos y palabras que se pueden usar: letras, dígitos, palabras reservadas, identificadores, literales y operadores.
- La sintaxis establece cómo se combinan esos elementos para formar instrucciones válidas.
- La semántica determina qué significa una construcción válida y qué efecto produce al ejecutarse.
Por ejemplo, en Java int total = 3 + 4; usa caracteres y palabras permitidos; también respeta la sintaxis de una declaración. Su semántica indica que se crea una variable entera llamada total con el valor 7.
Un error de cada tipo
En Python, total = 3 + 4 es una asignación válida. Escribir total = 3 + produce un error sintáctico porque falta un operando. En cambio, total = "tres" + 4 puede ser sintácticamente válido, pero genera un error al ejecutarse en Python porque esa operación no tiene el significado esperado para esos tipos de datos.
2. Clasificaciones complementarias de los lenguajes¶
Un mismo lenguaje puede pertenecer a varias categorías a la vez. Por ejemplo, Java suele considerarse de alto nivel, orientado a objetos y ejecutado sobre una máquina virtual; estas tres descripciones responden a preguntas diferentes.
Una clasificación no es una etiqueta absoluta
Las categorías simplifican la realidad. El modelo de ejecución depende a menudo de la implementación concreta: CPython interpreta bytecode, PyPy incorpora JIT y Java combina bytecode con compilación JIT. Por eso conviene explicar también qué compilador, intérprete o entorno se está utilizando.
2.1. Según el modo de ejecución¶
En un modelo de compilación anticipada o AOT (Ahead-Of-Time), el código fuente se traduce antes de ejecutarse a código nativo para una plataforma determinada. C, C++, Go y Rust se usan habitualmente de esta forma. El resultado puede arrancar directamente en la CPU, aunque suele ser necesario generar una versión por arquitectura y sistema operativo de destino.
Por ejemplo, GCC puede compilar ese programa con gcc hola.c -o hola. El archivo hola contiene código nativo para la plataforma donde se haya generado.
En la interpretación, un intérprete procesa el código fuente o, con frecuencia, una representación intermedia durante la ejecución. Python, JavaScript, Ruby y PHP suelen emplear entornos de este tipo. Facilitan un ciclo rápido de edición y prueba, pero el sistema necesita el intérprete o entorno de ejecución correspondiente.
En CPython, python hola.py no ejecuta el archivo fuente línea por línea de forma literal: normalmente lo transforma en bytecode y la máquina virtual de Python procesa ese bytecode. Por tanto, «compilado» e «interpretado» son modelos útiles para empezar, no compartimentos estancos.
| Modelo habitual | Qué se distribuye o ejecuta | Ejemplos representativos | Consecuencia principal |
|---|---|---|---|
| Compilación AOT | Ejecutable o biblioteca nativa | C, C++, Go, Rust | Buen control sobre el binario, con dependencia de la plataforma. |
| Interpretación o bytecode interpretado | Código fuente o bytecode más intérprete | Python, PHP, Ruby | Ciclo de prueba ágil; el intérprete forma parte del despliegue. |
| Máquina virtual con JIT | Bytecode más entorno de ejecución | Java, Kotlin en JVM, C# en .NET | Portabilidad dentro del entorno compatible y optimización durante la ejecución. |
2.2. Según el nivel de abstracción¶
Los lenguajes de alto nivel se alejan de los detalles del hardware para que sea más sencillo expresar soluciones: suelen ofrecer bibliotecas amplias, tipos de datos ricos y, en muchos casos, gestión automática de memoria. Python, Java, C# y JavaScript son ejemplos habituales.
Los lenguajes de bajo nivel proporcionan un control más próximo a la máquina, por ejemplo sobre registros, memoria o instrucciones. El ensamblador es el ejemplo más claro. C se sitúa cerca del sistema y ofrece mucho control, aunque también aporta abstracciones de alto nivel; por ello, clasificarlo simplemente como «bajo nivel» es una aproximación útil, no una descripción completa.
MOV AX, 0005h ; Carga el valor 5 en AX
MOV BX, 0003h ; Carga el valor 3 en BX
ADD AX, BX ; Suma ambos valores y guarda el resultado en AX
| Aspecto | Alto nivel | Bajo nivel |
|---|---|---|
| Cercanía al hardware | Oculta muchos detalles de la máquina. | Permite controlar detalles de memoria, registros o instrucciones. |
| Productividad | Suele facilitar la lectura, el desarrollo y el mantenimiento. | Exige más trabajo y conocimiento de la plataforma. |
| Uso habitual | Aplicaciones web, automatización, negocio, datos. | Firmware, controladores, sistemas operativos o partes críticas. |
Más bajo nivel no significa siempre mejor rendimiento
Elegir un lenguaje cercano al hardware puede ser necesario en un controlador o un dispositivo con memoria limitada, pero añade complejidad y riesgos de seguridad. En muchos proyectos, la productividad, las bibliotecas disponibles y la mantenibilidad aportan más valor que una optimización prematura.
2.3. Según el paradigma de programación¶
Un paradigma es una forma de organizar el razonamiento y el código. Muchos lenguajes actuales son multiparadigma: permiten combinar estilos cuando resulta útil.
| Paradigma | Idea central | Ejemplos de lenguajes | Situación representativa |
|---|---|---|---|
| Imperativo | Indica los pasos y cómo cambia el estado. | C, C++, Java, Kotlin, Python | Recorrer una lista y acumular un resultado. |
| Funcional | Compone funciones y favorece datos inmutables y transformaciones declarativas. | Haskell, Lisp, Erlang, Scala; también Kotlin, JavaScript y Python | Transformar, filtrar y agregar datos. |
| Orientado a objetos | Organiza el software en objetos que combinan estado y comportamiento. | Java, C#, Python, Kotlin, C++ | Modelar entidades como pedidos, clientes o vehículos. |
En estilo imperativo se describen los pasos de forma explícita:
En estilo funcional se define una transformación a partir de entradas y salidas:
La orientación a objetos resulta práctica cuando el problema contiene entidades con datos y comportamientos relacionados:
Combinar paradigmas en una aplicación
En una aplicación de biblioteca se pueden usar clases Libro, Usuario y Prestamo para modelar el dominio. Al mismo tiempo, una colección de préstamos puede filtrarse y transformarse con operaciones funcionales, y el proceso de alta de un préstamo puede expresarse mediante pasos imperativos. Elegir un estilo no obliga a renunciar a los demás.
3. Elementos presentes en los programas¶
Aunque cada lenguaje tiene su sintaxis, la mayoría comparten elementos que permiten almacenar información, operar con ella y controlar el flujo de ejecución.
| Elemento | Para qué sirve | Ejemplo o aclaración |
|---|---|---|
| Datos | Representan la información con la que trabaja el programa. | Números, texto, valores lógicos, listas, registros, imágenes o ficheros. |
| Variables y constantes | Asocian un nombre a un valor; el tipo determina qué operaciones son válidas. | Una constante no debe cambiar durante su uso; una variable puede recibir otro valor. |
| Expresiones y operadores | Calculan valores o comparan información. | +, -, *, /, módulo, concatenación, comparación y operadores lógicos. |
| Instrucciones | Indican una acción que debe realizar el programa. | Declarar, asignar, leer, mostrar o llamar a una función. |
| Comentarios | Documentan decisiones para las personas que leen el código. | No forman parte del comportamiento ejecutable. |
Las instrucciones pueden organizarse con varias estructuras de control:
- Secuencial: se ejecutan en orden, una tras otra.
- Condicional:
if,if elseoswitchpermiten elegir según una condición. - Repetitiva:
while,do whileyforrepiten acciones mientras se cumpla una condición o para una colección de valores.
Operadores: la notación cambia entre lenguajes
Conceptos como suma, comparación, negación y conjunción lógica son comunes, pero sus símbolos no siempre coinciden. Por ejemplo, la igualdad puede escribirse == en muchos lenguajes y la potencia puede ser ** en Python, no ^. Consulta siempre la especificación o documentación del lenguaje antes de trasladar una expresión.
4. Características de lenguajes comunes y tendencias¶
La siguiente tabla reúne características habituales. No pretende escoger un ganador, sino ofrecer un punto de comparación para razonar sobre el contexto de uso.
| Lenguaje | Abstracción y ejecución habituales | Paradigmas | Usos frecuentes |
|---|---|---|---|
| Python | Alto nivel; CPython compila a bytecode y lo interpreta. | Imperativo, orientado a objetos y funcional. | Automatización, web, ciencia de datos, aprendizaje y prototipado. |
| Java | Alto nivel; compila a bytecode para la JVM, que puede usar JIT. | Principalmente orientado a objetos, con rasgos funcionales modernos. | Backend, aplicaciones empresariales y ecosistema Android existente. |
| C | Próximo al sistema; normalmente compilación AOT a código nativo. | Imperativo y procedimental. | Sistemas operativos, firmware, controladores y software con restricciones de recursos. |
| JavaScript | Alto nivel; los motores modernos interpretan y optimizan con JIT. | Imperativo, orientado a objetos basado en prototipos y funcional. | Interfaces web y servicios de servidor con Node.js. |
| Kotlin | Alto nivel; habitualmente bytecode JVM, aunque admite otros destinos. | Orientado a objetos y funcional. | Android, backend y proyectos que aprovechan interoperabilidad con Java. |
Las tendencias ayudan a observar el ecosistema, pero deben interpretarse con prudencia. El índice TIOBE se actualiza mensualmente a partir de datos de búsqueda en varios motores; es un indicador de interés, no una medida directa de líneas de código en producción ni de calidad técnica. Para una visión más completa se puede contrastar con encuestas profesionales, repositorios y las ofertas de empleo del sector.
La evolución tampoco implica la desaparición automática de los lenguajes consolidados. Kotlin aporta, entre otras características, seguridad frente a nulos, corrutinas y una sintaxis más concisa, pero puede convivir con Java porque ambos se integran en la JVM. Del mismo modo, C y C++ siguen teniendo un papel importante cuando el rendimiento, el tamaño o el acceso al hardware son restricciones esenciales.
5. Elegir un lenguaje con criterios técnicos¶
La elección se convierte en una decisión razonada cuando se identifican primero las restricciones reales del proyecto:
flowchart TD
A["Necesidad del proyecto"] --> B{"¿Requiere control directo<br/>del hardware o recursos muy limitados?"}
B -->|"Sí"| C["Valorar C o ensamblador"]
B -->|"No"| D{"¿Necesita integrarse con una plataforma<br/>o un ecosistema concreto?"}
D -->|"JVM o Android"| E["Valorar Java o Kotlin"]
D -->|"Navegador"| F["Valorar JavaScript o TypeScript"]
D -->|"Datos, automatización o prototipo"| G["Valorar Python"]
D -->|"Otro contexto"| H["Comparar requisitos, bibliotecas y equipo"]
El diagrama sirve para iniciar el análisis, no para cerrar la decisión. Antes de escoger conviene seguir estos pasos:
- Define el problema y las restricciones: rendimiento, memoria, latencia, seguridad, plataforma de despliegue, accesibilidad y vida útil prevista.
- Revisa el ecosistema: bibliotecas, herramientas de prueba, documentación, soporte de la comunidad y compatibilidad con los sistemas existentes.
- Considera al equipo y el mantenimiento: un lenguaje conocido, legible y bien soportado reduce el coste de incorporar cambios y corregir incidencias.
- Valida la decisión con una prueba pequeña: construye un prototipo, mide lo que sea crítico y documenta los compromisos adoptados.
6. Buenas prácticas¶
- Describe la implementación, no solo la etiqueta: indica si trabajas con CPython, la JVM, Node.js o un compilador concreto cuando hables del modo de ejecución.
- Elige según requisitos verificables: usa medidas de rendimiento, consumo y compatibilidad cuando estos aspectos sean relevantes; no decidas solo por preferencias personales.
- Aprovecha los lenguajes multiparadigma con coherencia: combina estilos cuando resuelvan mejor una parte del problema, pero mantén convenciones claras para que el código sea legible.
- Documenta las decisiones técnicas: deja constancia de por qué se eligió un lenguaje, qué dependencias requiere y qué limitaciones se aceptan.
- Consulta documentación primaria: la especificación del lenguaje y la documentación de su entorno de ejecución son más fiables que una clasificación simplificada o un ranking.
7. Errores frecuentes¶
| Error frecuente | Por qué ocurre | Cómo evitarlo |
|---|---|---|
| Creer que un lenguaje es únicamente compilado o interpretado. | Se confunde el lenguaje con una implementación concreta y se ignoran bytecode o JIT. | Indica el compilador, intérprete o máquina virtual y el artefacto que procesa. |
| Considerar C un lenguaje de bajo nivel en todos los sentidos. | Su cercanía al sistema se simplifica como una etiqueta absoluta. | Explica que ofrece abstracciones de alto nivel, aunque permite control y eficiencia próximos al sistema. |
| Pensar que la programación funcional es «usar funciones». | Se omiten ideas como composición, inmutabilidad y control de efectos. | Diferencia el uso de una función de adoptar un estilo funcional. |
| Elegir por un ranking de popularidad. | Un índice resulta fácil de consultar, pero no mide todas las necesidades del proyecto. | Combina tendencias con requisitos técnicos, ecosistema, mantenimiento y pruebas. |
| Suponer que un lenguaje de alto nivel no puede interactuar con hardware. | Se confunden bibliotecas de usuario con controladores del sistema. | Distingue entre usar una API desde Python y escribir el controlador de bajo nivel que accede al dispositivo. |
8. Resumen¶
En este tema has aprendido que:
- un lenguaje se define mediante reglas léxicas, sintácticas y semánticas;
- las clasificaciones por ejecución, abstracción y paradigma son complementarias;
- los programas combinan datos, variables, expresiones, instrucciones, estructuras de control y comentarios;
- Python, Java, C, JavaScript y Kotlin responden a necesidades y ecosistemas diferentes;
- una elección profesional se apoya en requisitos, evidencias y mantenimiento, no en una única etiqueta.
Idea clave
Clasificar un lenguaje permite anticipar sus compromisos, pero elegirlo exige analizar el problema completo: plataforma, recursos, herramientas, equipo y evolución prevista de la aplicación.
9. Para seguir practicando¶
- Clasifica Python, Java, C, JavaScript y Kotlin según las tres perspectivas del tema; para cada caso, escribe una frase sobre la implementación o entorno de ejecución que estás considerando.
- Diseña una tabla de decisión para tres proyectos: firmware de un sensor, aplicación web de una biblioteca y análisis de datos de ventas. Justifica la elección sin usar «es el más popular» como argumento.
Bibliografía y fuente¶
- Python Software Foundation, modelo de ejecución de Python.
- Oracle, Java Virtual Machine Specification.
- ISO C Working Group, documentos y borradores del estándar C.
- MDN Web Docs, JavaScript Guide.
- Kotlin, documentación oficial.
- TIOBE, TIOBE Programming Community Index.