Lenguajes de programación

Un lenguaje de programación es un conjunto de reglas y sintaxis que permiten a los desarrolladores escribir instrucciones que un computador puede entender y ejecutar.
El objetivo principal de un lenguaje de programación es permitir la creación de programas que puedan resolver problemas, automatizar tareas, procesar datos y crear aplicaciones.
Requisitos de un lenguaje de programación
En informática no hay una definición única y universalmente aceptada de lo que es un lenguaje de programación, pero sí existen criterios que permiten distinguirlo de otros lenguajes formales o de especificación.
En general, para que un lenguaje sea considerado lenguaje de programación, debe cumplir con estos requisitos:
- Sintaxis formal y reglas gramaticales claras
- Debe existir una definición precisa de cómo se construyen las instrucciones (palabras clave, operadores, delimitadores, etc.).
- Estas reglas permiten escribir programas de manera no ambigua.
- Semántica bien definida
- No basta con que las instrucciones sean correctas sintácticamente, también deben tener un significado claro y consistente (qué efecto producen al ejecutarse).
- Capacidad de expresar algoritmos
- El lenguaje debe permitir describir secuencias de pasos para resolver un problema.
- Normalmente implica estructuras como:
- Secuencia (ejecutar una instrucción tras otra)
- Selección (if/else, condicionales)
- Iteración (bucles)
- Composición modular (funciones, procedimientos, métodos, etc.)
- Control de flujo y abstracción
- Debe ofrecer mecanismos para controlar el orden de ejecución (bucles, saltos, llamadas de funciones).
- Idealmente, también permitir niveles de abstracción (definir variables, tipos de datos, funciones, clases…).
- Turing-completitud (en la práctica)
- No es un requisito formal absoluto, pero la mayoría de lenguajes de programación se consideran tales si son Turing completos, es decir, si pueden simular cualquier máquina de Turing (resolver cualquier problema computable, dadas suficientes memoria y tiempo).
- Ejemplo: HTML no es un lenguaje de programación porque no es Turing completo, mientras que Python, C o Java sí lo son.
- Ejecutabilidad
- Debe existir la posibilidad de traducir o interpretar el código en acciones ejecutables por un computador (ya sea mediante compilación, interpretación o un híbrido).
Creación de un lenguaje de programación
Cualquier persona puede diseñar un lenguaje de programación siempre y cuando ese lenguaje cumpla con los requisitos fundamentales que se han mencionado en el apartado anterior. Eso significa que, si creas un sistema con una serie de símbolos y reglas que permitan describir y ejecutar procedimientos, has creado un lenguaje de programación.
Esto incluye tanto lenguajes serios para tareas prácticas, como lenguajes esotéricos, creados a menudo por diversión. Un lenguaje de programación esotérico es un lenguaje creado como experimento, broma o reto intelectual, no para uso práctico.
Esotérico significa algo difícil de entender o que está pensado solo para unas pocas personas con conocimientos especiales. Por ejemplo, un tema esotérico es aquel que resulta misterioso o poco claro para la mayoría.
Algunos ejemplos son:
Estos lenguajes suelen sorprender por su sintaxis curiosa o limitada, pero suelen ser Turing-completos y, por tanto, funcionales.
Curiosamente, Xataka publicó un artículo titulado 14 lenguajes de programación para partirse la caja pero que funcionan (más o menos), donde destaca precisamente esta idea: hay quien se divierte creando lenguajes con sintaxis absurdas o cómicas.
Este tipo de proyectos no solo son curiosos o humorísticos, sino que ilustran perfectamente que, más allá del propósito práctico, lo esencial es que el lenguaje permita ejecutar procesos. Y si el propósito es divertir o explorar límites creativos, esos lenguajes cumplen perfectamente.
Sintaxis y semántica
Escribir un programa es como componer una obra: no basta con tener buenas ideas, también hay que saber plasmarlas de manera que la máquina pueda entenderlas. Cada instrucción, cada símbolo y cada estructura forman parte de un lenguaje con reglas propias, y dominar estas reglas marca la diferencia entre un código que funciona y otro que genera caos. Entre todas estas reglas, dos conceptos clave gobiernan cómo se construye y se interpreta un programa: la sintaxis y la semántica.
Sintaxis
La sintaxis de un lenguaje de programación (syntax) es el conjunto de reglas y estructuras que determinan cómo deben ser escritos los programas en un determinado lenguaje.
Estas reglas especifican la forma correcta de organizar y combinar palabras, símbolos y otros elementos léxicos para crear instrucciones válidas que un compilador o intérprete pueda entender y procesar. La sintaxis define la forma externa del código, sin entrar en su significado (que es tratado por la semántica).
La sintaxis se centra en la estructura y forma del código.
Por ejemplo, en el lenguaje C:
- Sintaxis correcta:
int x = 5; - Sintaxis incorrecta:
int x 5;. Falta el=y el;.
Semántica
La semántica de un lenguaje de programación (semantics) se refiere al significado de las instrucciones escritas en el lenguaje. Mientras que la sintaxis se encarga de la estructura y la forma correcta de escribir el código, la semántica describe lo que hace ese código cuando es ejecutado. La semántica define el comportamiento del programa, los efectos de las instrucciones y las relaciones entre diferentes elementos del código.
Por ejemplo, en el lenguaje C:
- Sintaxis:
int x = 5 / 0;cumple la sintaxis (no contiene errores de gramática) - Semántica: divide 5 entre 0, lo cual es problemático porque dividir entre cero no tiene un resultado definido.
Por ejemplo, en el lenguaje Python:
- Sintaxis:
print("Hola")está escrito de forma válida. - Semántica: el ordenador muestra en pantalla el texto
Hola.
Tipos de lenguajes de programación
Existen muchas formas de clasificar los lenguajes de programación, dependiendo de qué característica se desee destacar.
Los parámetros más comunes para realizar clasificaciones son:
- El nivel de abstracción.
- El paradigma de programación.
- La forma de ejecución.
- El tipo de tipado.
- La finalidad (o dominio).
- La licencia de uso y distribución.
Clasificaciones
Según el nivel de abstracción
El nivel de un lenguaje de programación se refiere al grado de abstracción que ofrece sobre el hardware y el sistema operativo, y puede influir en la complejidad, la flexibilidad y la eficiencia del desarrollo de software.
En los siguientes apartados veremos más detalles sobre esta clasificación.
| Tipo | Descripción | Lenguajes |
|---|---|---|
| De bajo nivel | Muy cercanos al hardware | Ensamblador |
| De alto nivel | Más orientados a la lógica del problema que a la máquina | Python, Java, JavaScript, PHP |
| De nivel medio | Tienen acceso al hardware, pero ofrecen abstracción | C |
Según el paradigma de programación
| Tipo | Descripción | Lenguajes |
|---|---|---|
| Imperativos | Se centran en dar instrucciones paso a paso | C, Fortran |
| Declarativos | Se centran en describir qué se quiere, no cómo | SQL, Prolog |
| Orientados a objetos (OOP) | Organizan el código en clases y objetos | Java, C++, Python, PHP |
| Funcionales | Basados en funciones matemáticas, evitan estados mutables | Haskell, Lisp, Elixir |
| Lógicos | Basados en reglas y relaciones lógicas | Prolog |
| Multiparadigma | Mezclan varios enfoques | Python, Scala, JavaScript, TypeScript |
Según la forma de ejecución
| Tipo | Descripción | Lenguajes |
|---|---|---|
| Compilados | Se traducen a código máquina antes de ejecutarse. | C, Rust |
| Interpretados | Se ejecutan línea por línea por un intérprete. | Python, Ruby |
| Híbridos | Combinan ambas técnicas. | Java, C# |
Según el tipo de tipado
| Tipo | Descripción | Lenguajes |
|---|---|---|
| Tipado estático | El tipo de datos se verifica en tiempo de compilación. | Java, C++, Rust |
| Tipado dinámico | El tipo de datos se decide en tiempo de ejecución. | Python, JavaScript |
| Tipado fuerte | No permite mezclar tipos sin conversión explícita. | Java |
| Tipado débil | Hace conversiones implícitas. | JavaScript |
Según la finalidad o dominio
| Tipo | Descripción | Lenguajes |
|---|---|---|
| De propósito general | Sirven para casi cualquier aplicación. | C, Python, Java |
| Específicos de dominio (DSL) | Diseñados para un uso concreto. | SQL, HTML, CSS, MATLAB |
Según la licencia de uso y distribución
| Tipo | Descripción | Lenguajes |
|---|---|---|
| Propietarios | Requieren licencia y/o son controlados por una empresa. | MATLAB |
| De código abierto | Su especificación y compiladores están abiertos. | Python, Go, Rust |
Clasificación de un lenguaje de programación
Un mismo lenguaje de programación puede pertenecer a varias categorías a la vez.
Por ejemplo, Python es de alto nivel, multiparadigma, interpretado, de tipado dinámico y fuerte, de propósito general y de código abierto.
Lenguajes de alto nivel
Un lenguaje de alto nivel es un tipo de lenguaje de programación que está más próximo al lenguaje humano y a la lógica matemática, en comparación con los lenguajes de bajo nivel.
Estos lenguajes están diseñados para ser fáciles de leer y escribir para las personas, abstrayendo las complejidades del hardware subyacente y permitiendo que los programadores se centren en la lógica y en la resolución de problemas, sin preocuparse por los detalles de la implementación del hardware.
Algunos ejemplos de estos lenguajes son:
- Python
- Java
- JavaScript
- TypeScript
- C#
- Ruby
- PHP
- Swift
- Kotlin
- Go
- Rust
- MATLAB
- R
- Perl
- Dart
- Visual Basic
- Objective-C
- Scala
- Haskell
Características
- Abstracción de hardware: Los lenguajes de alto nivel ocultan los detalles específicos del hardware, como la gestión de memoria y los códigos de máquina. Esto permite a los programadores escribir código sin preocuparse por la arquitectura específica del procesador.
- Sintaxis clara y legible: La sintaxis de los lenguajes de alto nivel está diseñada para ser semejante a la gramática de los lenguajes naturales o para seguir una lógica matemática, lo que facilita su comprensión y escritura.
- Portabilidad: El código escrito en lenguajes de alto nivel tiende a ser más portátil, ya que el mismo código puede ejecutarse en diferentes plataformas con pocas o ninguna modificación, gracias a la presencia de compiladores o intérpretes específicos para cada plataforma.
- Bibliotecas y frameworks: Los lenguajes de alto nivel pueden venir acompañados de bibliotecas (también llamadas librerías) y frameworks que proporcionan funcionalidades avanzadas y herramientas para facilitar el desarrollo de aplicaciones complejas.
Ventajas
- Facilidad de desarrollo: La sintaxis simplificada y la abstracción del hardware permiten un desarrollo más rápido y menos propenso a errores.
- Lectura y mantenimiento: El código en lenguajes de alto nivel es generalmente más legible y más fácil de mantener y modificar, gracias a su sintaxis clara y a su estructura organizada.
- Productividad: Permiten a los programadores ser más productivos, ya que no tienen que preocuparse tanto por los detalles de bajo nivel y pueden centrarse en la resolución de problemas y en la creación de funcionalidades.
- Depuración y pruebas: Las herramientas de depuración y las bibliotecas de pruebas son más sofisticadas y están más disponibles para lenguajes de alto nivel, facilitando la detección y corrección de errores.
Desventajas
- Rendimiento: Los lenguajes de alto nivel pueden ser menos eficientes en términos de rendimiento en comparación con lenguajes de bajo nivel, debido a la sobrecarga introducida por la abstracción y la interpretación o compilación del código.
- Menor control sobre el hardware: La abstracción puede limitar el control directo sobre el hardware, lo que puede ser importante en aplicaciones de tiempo real.
Lenguajes de bajo nivel
Un lenguaje de bajo nivel es un tipo de lenguaje de programación que está más próximo a la arquitectura del hardware del computador, proporcionando menos abstracción en comparación con los lenguajes de alto nivel.
Estos lenguajes permiten un mayor control sobre los recursos del sistema y las operaciones de bajo nivel, pero también requieren una comprensión más profunda de la arquitectura del hardware y su operación.
Características
- Control detallado sobre el hardware: Los lenguajes de bajo nivel proporcionan un acceso directo a la memoria y a las operaciones del procesador, permitiendo a los programadores controlar con precisión el funcionamiento del hardware.
- Menor abstracción: Estos lenguajes ofrecen poca o ninguna abstracción en comparación con los lenguajes de alto nivel. Esto significa que los programadores deben manejar detalles como la gestión de memoria y las operaciones aritméticas a nivel de bits y bytes.
- Eficiencia: El código escrito en lenguajes de bajo nivel tiende a ser más eficiente en términos de rendimiento, ya que se ejecuta más cerca del hardware y puede ser optimizado para tareas específicas.
- Sintaxis compleja: La sintaxis de los lenguajes de bajo nivel es generalmente más compleja y menos legible para los seres humanos en comparación con los lenguajes de alto nivel.
Ejemplos
- Lenguaje máquina (machine languaje): Es el lenguaje más bajo y próximo al hardware, compuesto por instrucciones en código binario que el procesador puede ejecutar directamente. No requiere traducción adicional, pero es extremadamente difícil de leer y escribir para las personas. El código binario específico para una instrucción, como
10110000 01100001, puede corresponder a una operación de mover datos en la memoria. - Lenguaje ensamblador (assembly): Es un lenguaje de bajo nivel que usa abreviaturas y símbolos para representar instrucciones de código máquina. Cada instrucción de ensamblador corresponde a una operación de bajo nivel que el procesador puede realizar. Menos abstracta que los lenguajes de alto nivel, pero más comprensible para los humanos que el lenguaje máquina.
A modo de ejemplo, vamos a ver un ejemplo de cómo cargar el número 42 en el registro EAX de un procesador x86 (un procesador muy usado en equipos actuales):
-
Lenguaje máquina: Este es lo que ve realmente el procesador, una secuencia de ceros y unos, que normalmente se representa en hexadecimal para simplificar. Los siguientes bytes son el código máquina de una instrucción en x86 (tanto en hexadecimal como en binario).
B8 2A 00 00 0010111000 00101010 00000000 00000000 00000000 -
Ensamblador: El mismo programa, pero escrito de forma legible para humanos:
mov eax, 42
Ventajas
- Eficiencia y rendimiento: El código escrito en lenguajes de bajo nivel puede ser más eficiente y rápido debido a su proximidad al hardware.
- Control completo: Permiten un control total sobre las operaciones del procesador y la memoria, lo que es útil para tareas que requieren un alto rendimiento o que están muy próximas al hardware, como sistemas operativos y controladores de dispositivos.
- Optimización de recursos: La programación en bajo nivel puede optimizar el uso de los recursos del sistema para aplicaciones específicas.
Desventajas
- Complejidad: La programación en lenguajes de bajo nivel es compleja y requiere una comprensión detallada del hardware. El código es menos legible y más difícil de mantener y depurar.
- Portabilidad: El código escrito en lenguajes de bajo nivel puede ser menos portátil entre diferentes arquitecturas de hardware, ya que está fuertemente vinculado a un tipo específico de procesador o sistema.
- Tiempo de desarrollo: El desarrollo y depuración de código en bajo nivel puede llevar más tiempo debido a su complejidad y al nivel de detalle requerido.
Lenguajes de nivel medio
Un lenguaje de programación de nivel medio combina características de los lenguajes de alto nivel (más cercanos al lenguaje humano y fáciles de usar) con características de bajo nivel (más cercanas al hardware y al control directo de la memoria). Esto permite tanto programar de manera relativamente sencilla como acceder a funciones de bajo nivel cuando se necesita eficiencia o control.
Un ejemplo clásico de lenguaje de nivel medio es C, que permite manipular directamente memoria y hardware, pero también escribir programas estructurados y legibles.
El lenguaje de programación C
El lenguaje de programación C es uno de los lenguajes más influyentes y utilizados en la historia de la informática. Fue desarrollado a principios de los años 70 por Dennis Ritchie en los laboratorios Bell para crear el sistema operativo UNIX, y se caracteriza por su eficiencia, flexibilidad y capacidad de trabajar cerca del hardware. C combina elementos de lenguajes de alto nivel con acceso a operaciones de bajo nivel, lo que lo convierte en un lenguaje de nivel medio ideal tanto para desarrollar sistemas operativos, compiladores y programas de alto rendimiento como para aprender los fundamentos de la programación y la estructura de los computadores. Su sintaxis sencilla pero poderosa ha servido de base para muchos otros lenguajes modernos, como C++, C# y Java.
Características como lenguaje de alto nivel
- Sintaxis clara y legible: C tiene una sintaxis relativamente clara que permite escribir código de manera eficiente y organizada, similar a otros lenguajes de alto nivel.
- Bibliotecas y funciones standard: Incluye una biblioteca estándar rica que proporciona una amplia gama de funciones para manipulación de cadenas, entrada/salida, matemáticas y manipulación de memoria.
- Portabilidad: El código C puede ser portado entre diferentes sistemas operativos y arquitecturas de hardware con pocas modificaciones, debido a su amplia aceptación y soporte.
Características como lenguaje de bajo nivel
- Acceso directo a memoria: C permite manipular directamente la memoria mediante el uso de punteros, lo que ofrece un control detallado sobre la memoria y las operaciones del hardware.
- Manipulación de bits y bytes: Permite operaciones a nivel de bits y bytes, lo que es útil para tareas que requieren una manipulación precisa de los datos.
- Control sobre la gestión de recursos: Permite un control detallado sobre el flujo de ejecución y la gestión de recursos del sistema. Esto es especialmente útil para programar sistemas operativos, controladores de dispositivos y software de alto rendimiento.
Ventajas
- Eficiencia y rendimiento: C es conocida por su eficiencia y capacidad de generar código que se ejecuta rápidamente. Esto la hace ideal para aplicaciones de alto rendimiento y programaciones de sistema.
- Versatilidad: Puede ser usada para desarrollo de sistemas operativos, compiladores, controladores de dispositivos y software de aplicación.
- Control y flexibilidad: Ofrece un alto grado de control sobre la memoria y el hardware, permitiendo optimizaciones y personalizaciones precisas.
Desventajas
- Seguridad y robustez: La manipulación directa de la memoria y la falta de comprobaciones automáticas de tipos pueden llevar a errores difíciles de detectar, como violaciones de acceso a memoria y fugas de memoria.
- Complejidad de depuración: El código en C puede ser más difícil de depurar debido a su complejidad y la posibilidad de errores sutiles asociados con la manipulación de punteros y memoria.
Paradigmas de programación
Un paradigma de programación es un estilo o enfoque fundamental que guía la manera en que se desarrolla y organiza el código en un programa informático. Es como una manera de ver el problema y escribir la solución.
Cada paradigma tiene sus propias reglas, conceptos y técnicas para resolver problemas y estructurar el código, influyendo en la forma en que se escriben e interpretan los programas.
Los paradigmas ayudan a definir la forma en que los problemas son modelados y resueltos mediante la programación.
En los siguientes apartados vamos a ver los siguientes paradigmas:
- Programación imperativa.
- Programación estructurada.
- Programación orientada a objetos (POO).
- Programación funcional.
- Programación lógica.
- Programación declarativa.
- Paradigmas híbridos.
Lenguajes de programación y paradigmas
Un lenguaje de programación se enmarca en un paradigma según cómo está pensado para que tú escribas el código y cómo maneja los problemas:
- Qué tipo de instrucciones permite o facilita
- Por ejemplo, C facilita escribir instrucciones paso a paso → imperativo.
- Haskell facilita usar funciones matemáticas sin cambiar variables → funcional.
- Cómo organiza los datos y la lógica
- Python permite agrupar datos y funciones en objetos → orientado a objetos.
- SQL organiza todo en tablas y consultas → declarativo.
- Qué estilo hace más natural escribir
- Algunos lenguajes permiten mezclar estilos, pero siempre hay uno que predomina y define su "paradigma principal".
El paradigma es como el «enfoque mental» que el lenguaje te sugiere usar para resolver problemas, y el lenguaje se diseña para que ese enfoque sea cómodo y eficiente.
Un lenguaje puede enmacarse en múltiples paradigmas. Un lenguaje multiparadigma es aquel que permite programar usando varios estilos o paradigmas diferentes dentro del mismo lenguaje. Ejemplos de lenguajes multiparadigma son Python, JavaScript, C++, Ruby, C# y Kotlin, entre otros.
El paradigma estructurado, el orientado a objetos y el funcional se estudiarán en las unidades 2, 4, 5 y 6.
Programación imperativa
La programación imperativa es uno de los paradigmas más antiguos y fundamentales en informática. Su enfoque se basa en dar órdenes explícitas a la computadora sobre cómo realizar una tarea, describiendo paso a paso los cambios en el estado del programa.
El programa se concibe como una secuencia de instrucciones que modifican el estado de la memoria. El programador debe especificar exactamente cómo se debe lograr el resultado.
Algunos lenguajes que siguen (o pueden seguir) este paradigma son C, C++, Python, Java, JavaScirpt, TypeScript, PHP, Ruby, Go, Kotlin, Swift, C#, Pascal, Fortran y BASIC.
Un ejemplo escrito en C sería el siguiente:
#include <stdio.h>
int main() {
int suma = 0;
suma = suma + 7;
printf("La suma es: %d\n", suma);
return 0;
}
Características
- Variables y asignaciones: Se usan para almacenar y actualizar datos. Por ejemplo,
int x = 5;yx = x + 2;. - Estructuras de control: Condicionales (
if,else) y bucles (for,while) determinan el flujo de ejecución. - Efectos secundarios: Las operaciones cambian el estado del sistema o de las variables.
- Secuencialidad: El orden de las instrucciones importa; cada paso se ejecuta en el orden especificado.
Ventajas
- Permite un control preciso y detallado sobre cómo se ejecuta el programa.
- Es intuitivo para tareas sencillas y procedimientos lineales.
- La mayoría de los lenguajes de programación clásicos son imperativos, por lo que hay mucha documentación y ejemplos disponibles.
Desventajas
- Puede ser menos modular y más difícil de mantener en programas grandes.
- El seguimiento del estado y los efectos secundarios puede generar errores complicados.
- Menos adecuado para la programación concurrente o paralela sin técnicas adicionales.
Programación estructurada
La programación estructurada es un paradigma de programación que se centra en la organización y control del flujo de ejecución del programa mediante el uso de estructuras de control claras y bien definidas. Se organiza el código en bloques claros y controlados.
El paradigma estructurado es un estilo de programación que organiza el código en bloques claros y controlados, evitando saltos incontrolados como el popular goto en lenguajes de programación imperativos antiguos. La función del goto es saltar directamente a otra parte del código, pero esto suele generar programas difíciles de entender. Los paradigmas estructurados evitan este problema usando bucles y condicionales claros.
El paradigma estructurado es en realidad una forma de programación imperativa más organizada. Por lo tanto, todo estructurado es imperativo, pero no todo código imperativo es estructurado
El objetivo principal de la programación estructurada es mejorar la legibilidad, el mantenimiento y la eficiencia del código mediante una estructura ordenada y modular.
Características
- Secuencia de instrucciones clara: el código se ejecuta paso a paso.
- Estructuras de control definidas: se usan condicionales (
if,switch) y bucles (for,while) en lugar de saltos arbitrarios. - Modularidad: se divide el programa en funciones o procedimientos para que cada parte tenga un propósito claro y sea más sencillo de mantener.
Ejemplo
Python es un lenguaje de programación que sige este paradigma. Veamos un ejemplo de cómo es el aspecto de código escrito en Python:
def suma_hasta(n):
suma = 0
for i in range(1, n+1):
suma += i
return suma
resultado = suma_hasta(5)
print(resultado) # Muestra 15
En el código anterior podemos ver:
- Uso de función → modularidad
- Bucle
for→ control de repetición estructurado - Variables y operaciones claras → secuencia definida
Programación orientada a objetos (POO)
La programación orientada a objetos (POO) es un paradigma de programación que organiza el código en objetos y clases, facilitando la modelización y la gestión de la complejidad en programas de gran tamaño. La POO está basada en varios conceptos clave que ayudan a estructurar el código de forma más natural y modular, permitiendo que los objetos representen entidades del mundo real o conceptos abstractos.
Python, además de ser un lenguaje que sigue la programación estructurada, también sige el paradigma orientado a objetos. De hecho, Python es un lenguaje multiparadigma.
A continuación, se muestra un ejemplo de cómo es el aspecto de código escrito en Python utilizando clases y objetos:
# Definición de la clase
class Persona:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
def saludar(self):
print(f"Hola, me llamo {self.nombre} y tengo {self.edad} años.")
# Crear un objeto (instancia) de la clase
persona1 = Persona("Ana", 25)
persona1.saludar()
El mismo ejemplo escrito en Java:
// Definición de la clase
class Persona {
private String nombre;
private int edad;
public Persona(String nombre, int edad) {
this.nombre = nombre;
this.edad = edad;
}
public void saludar() {
System.out.println("Hola, me llamo " + nombre + " y tengo " + edad + " años.");
}
}
// Crear un objeto (instancia) de la clase
public class Main {
public static void main(String[] args) {
Persona persona1 = new Persona("Ana", 25);
persona1.saludar();
}
}
Programación funcional
La programación funcional es un paradigma de programación que trata las funciones como elemento principal y enfatiza el uso de la composición de funciones para resolver problemas.
A diferencia de paradigmas como la programación imperativa u orientada a objetos, que se enfocan en manipular el estado y usar objetos, la programación funcional pone el foco en la transformación de datos y en definir cálculos a través de funciones matemáticas.
Un ejemplo en Haskell que suma los números del 1 al 5:
suma = sum [1..5]
-- Resultado: 15
El código anterior se caracteriza por:
- No hay variables que cambien.
- La función
sumdevuelve el resultado directamente.
Programación lógica
La programación lógica es un paradigma de programación basado en la lógica formal y en la deducción para resolver problemas. Este enfoque está centrado en expresar lo que se quiere lograr mediante reglas y hechos y permitir que el sistema deduzca las soluciones a partir de estas declaraciones.
Es fundamentalmente diferente de los paradigmas imperativos y orientados a objetos, ya que no especifica una secuencia explícita de pasos para resolver un problema, sino que define relaciones y deja que el sistema deduzca las respuestas.
Los conceptos clave de la programación lógica son:
- Hechos: Declaraciones que describen información o verdaderos enunciados sobre el dominio del problema. Representan conocimientos básicos que se aceptan como verdaderos.
- Reglas: Declaraciones que definen cómo derivar nuevos hechos a partir de hechos existentes. Las reglas consisten en una cabeza (el hecho derivado) y un cuerpo (condiciones necesarias para que la cabeza sea verdadera).
- Consultas: Preguntas o consultas hechas al sistema para deducir información basada en hechos y reglas. El sistema usa un proceso de deducción para responder a las consultas.
- Inferencia: El proceso mediante el cual el sistema deduce nueva información o respuestas basadas en hechos y reglas. La inferencia puede ser automática y está basada en algoritmos de resolución, como el algoritmo de resolución.
- Unificación: El proceso de igualar términos y sustituir variables para que las reglas y hechos se apliquen correctamente durante la inferencia.
- Resolución: El método de deducción usado para determinar si una consulta es verdadera o falsa al buscar una coincidencia entre la consulta y los hechos o reglas existentes.
Ejemplo
Ejemplo en Prolog:
% Hechos
hombre(juan).
mujer(maria).
% Regla
mortal(X) :- hombre(X).
% Pregunta
?- mortal(juan).
% Respuesta: true
En este código podemos ver que preguntamos a partir de unos hechos y unas reglas definidas previamente. Es decir, definimos qué es verdad en el problema, pero no los pasos exactos para resolverlo.
hombre(juan)ymujer(maria)son hechos.mortal(X) :- hombre(X)es una regla: “X es mortal si X es hombre”.- La pregunta es si Juan es mortal. Prolog deduce automáticamente mediante inferencia que Juan es mortal.
Programación declarativa
La programación declarativa es un paradigma que se centra en describir qué se quiere lograr, en lugar de indicar cómo lograrlo. Es decir, el programador especifica el resultado deseado, y no el procedimiento paso a paso para conseguirlo. Este enfoque es muy distinto al de la programación imperativa, donde el control explícito del flujo de ejecución es fundamental.
Este paradigma se centra en el «qué», no en el «cómo». El lenguaje o el motor de ejecución se encarga de decidir cómo lograr el resultado especificado. Reduce la complejidad al abstraer los detalles de implementación.
Algunos ejemplos de lenguajes de programación que siguen este paradigma son: SQL, Prolog, Haskell, Lisp, Erlang, XSLT, HTML, CSS, F#, Clojure.
SQL es un lenguaje para realizar consultas en bases de datos. Un ejemplo escrito en SQL es el siguiente:
SELECT nombre, edad FROM personas WHERE edad > 18;
Se especifica lo que queremos obtener (nombre de personas mayores de 18), pero no se indica cómo recorrer la base de datos ni cómo filtrar los registros.
Características
- No se manejan efectos secundarios: Las funciones o expresiones no cambian el estado del programa.
- Alta abstracción: Se describen relaciones, reglas o propiedades que deben cumplirse.
- Orientada a la lógica o a los datos: Los programas suelen consistir en declaraciones, consultas o expresiones.
- Facilita la optimización automática: El motor del lenguaje puede reorganizar internamente la ejecución para mejorar eficiencia.
Ventajas
- Código más legible y mantenible, porque describe directamente el objetivo.
- Menor riesgo de errores por efectos secundarios o manejo de estado.
- Ideal para tareas como consultas de bases de datos, procesamiento de datos o programación lógica.
Desventajas
- Menor control sobre cómo se ejecutan las operaciones, lo que puede generar problemas de rendimiento en ciertos casos.
- Puede requerir un motor de ejecución más sofisticado para interpretar correctamente las declaraciones.
Multiparadigma
La programación híbrida (o multiparadigma) es un enfoque que combina características de varios paradigmas de programación en un mismo lenguaje o proyecto. Esto permite aprovechar las ventajas de cada paradigma y adaptarse mejor a distintos tipos de problemas, ofreciendo flexibilidad y eficiencia en el desarrollo de software.
El concepto principal del multiparadigma es que no se limita a un solo estilo de programación. Permite que un mismo programa use programación imperativa, orientada a objetos, funcional o declarativa, según lo requiera la situación. Facilita el desarrollo de aplicaciones complejas, donde un único paradigma podría ser insuficiente o poco práctico.
Ejemplos de lenguajes híbridos son:
- Python: soporta programación imperativa, orientada a objetos y funcional.
- Scala: combina orientada a objetos y funcional.
- F#: funcional y orientada a objetos.
- JavaScript: permite programación imperativa, orientada a objetos y funcional.
- C++: soporta programación imperativa, estructurada y orientada a objetos.
Python, como hemos visto, se trata de un lenguaje multiparadigma. En el siguiente ejemplo se puede ver cómo mezcla diferentes paradigmas:
# Imperativo
total = 0
for i in range(5):
total += i
# Funcional
cuadrados = list(map(lambda x: x**2, range(5)))
# Orientado a objetos
class Persona:
def __init__(self, nombre):
self.nombre = nombre
p = Persona("Ana")
Características
- Multifacético: El programador puede elegir el paradigma más adecuado para cada módulo o componente.
- Reutilización y modularidad: Combina la estructura modular de la POO con la eficiencia y claridad de paradigmas funcionales o declarativos.
- Flexibilidad: Se adapta a diferentes estilos de resolución de problemas.
- Soporte de lenguaje: Muchos lenguajes modernos están diseñados para ser híbridos, permitiendo distintos enfoques dentro del mismo código.
Ventajas
- Versatilidad: Permite aplicar la mejor técnica según la tarea, por ejemplo: POO para modelar objetos del mundo real, funcional para procesar colecciones de datos, imperativa para control detallado del flujo.
- Mantenimiento y escalabilidad: Facilita la organización del código en proyectos grandes.
- Aprovecha lo mejor de cada paradigma: Reduce limitaciones de paradigmas puros.
Desventajas
- Puede aumentar la complejidad conceptual si se mezclan demasiados estilos.
- Requiere que el programador tenga conocimiento de varios paradigmas.
- Puede dificultar la consistencia del código si no se aplican buenas prácticas.
Compiladores e intérpretes
Un lenguaje de programación está diseñado para ser sencillo de leer y escribir por personas. Pero el hardware de un equipo no es capaz de comprender este lenguaje.
Un equipo, y más concretamente una CPU, entiende únicamente un lenguaje llamado código máquina. Este código máquina es muy simple para la máquina pero muy pesado de escribir para una persona, ya que solo consta de ceros y unos:
El código máquina parece sencillo a simple vista, pero su sintaxis es más compleja y enrevesada que la de un lenguaje de programación de alto nivel. Muy pocos programadores escriben en este lenguaje y solo lo utilizan con fines muy concretos.
En lugar de eso, se crearon programas traductores que permiten a los programadores escribir en lenguajes de alto nivel y, a través de estos traductores, convertir los programas en código máquina (ceros y unos).
Dado que el código máquina está ligado al hardware de la máquina que lo ejecuta, este código no es portable entre equipos de diferente tipo. Los programas escritos en lenguajes de alto nivel pueden ser traducidos entre distintas máquinas usando traductores distintos.
Estos traductores se pueden dividir en dos grandes bloques: compiladores e intérpretes.
Compiladores
Los compiladores son programas que necesitan un archivo que contiene el código fuente (source code) y luego ejecutan el proceso de traducción del código fuente a lenguaje máquina (proceso de compilación). El código máquina resultante se coloca en un nuevo archivo para su ejecución posterior. Este archivo se suele denominar fichero binario ejecutable.
Ejemplos de lenguajes de programación que utilizan compilador son: C, C++, Rust, Go, Fortran, Pascal, Swift, Kotlin, Haskell y Ada.

En sistemas Windows estos ejecutables tienen la extensión .exe o .dll.
Si abrimos un archivo con código máquina en un archivo de texto veríamos algo totalmente ilegible:

Una vez tengamos un ejecutable, no es posible obtener el código fuente original. Se trata de un proceso irreversible. Sólo es posible deducir el código fuente a partir de un ejecutable mediante ingeniería inversa.
Funcionamiento de un compilador
El funcionamiento de un compilador se estructura de la siguiente manera:
- Análisis léxico: El compilador lee el código fuente y lo divide en unidades léxicas llamadas tokens (como palabras clave, identificadores, operadores, etc.).
Por ejemplo, la instrucción
int x = 5;se divide en tokens comoint,x,=,5, y;. - Análisis sintáctico: El compilador analiza la estructura del código para asegurarse de que sigue la sintaxis del lenguaje. Este paso construye un árbol de análisis sintáctico que representa la estructura del programa. Por ejemplo, la instrucción
int x = 5;se analiza para verificar que la declaración es válida dentro del contexto del lenguaje. - Análisis semántico: El compilador verifica el significado del código y se asegura de que el uso de las variables, tipos de datos y operaciones sea coherente y correcto. Por ejemplo, verifica que
xsea una variable que puede ser asignada y que5es un valor compatible con el tipoint. - Optimización: El compilador aplica diversas técnicas para mejorar el código, reducir el tamaño del código y mejorar el desempeño. Esta etapa puede optimizar tanto el código fuente como el código intermedio. Por ejemplo, puede simplificar operaciones matemáticas o eliminar código innecesario.
- Generación de código: El compilador traduce la representación interna del código a código de máquina o a un código intermedio que puede ser ejecutado por un procesador. Por ejemplo, la instrucción
int x = 5;se traduce a un conjunto de instrucciones que la CPU puede ejecutar para asignar el valor5a la variablex. - Enlazado: El compilador o un enlazador externo combina el código objeto generado con las bibliotecas y módulos necesarios para crear el archivo ejecutable final.
Ventajas
- Desempeño: El código compilado puede ejecutarse mucho más rápido que el código interpretado, ya que está convertido en código de máquina que la CPU puede ejecutar directamente.
- Optimización: Los compiladores aplican diversas técnicas de optimización que mejoran la eficiencia del código ejecutado.
- Detección de errores: Los compiladores realizan un análisis exhaustivo del código fuente (denominado análisis estático) y pueden detectar errores e inconsistencias antes de la ejecución, lo que facilita la corrección de problemas.
- Independencia del código fuente: Una vez compilado, el código objeto o ejecutable no requiere la presencia del compilador para ser ejecutado, permitiendo la distribución y ejecución del software sin dependencias adicionales.
Desventajas
- Tiempo de compilación: La compilación puede llevar tiempo, especialmente para programas grandes o complejos, lo que puede ralentizar el proceso de desarrollo y depuración.
- Flexibilidad: La modificación y prueba de código pueden ser menos flexibles en comparación con la interpretación, ya que cada cambio requiere recompilación.
- Complejidad: El proceso de compilación puede ser complejo y requiere una comprensión profunda del funcionamiento del compilador y de las técnicas de optimización.
Intérpretes
Los intérpretes leen el código fuente (el programa escrito en el lenguaje de alto nivel) de los programas tal y como lo escribió el programador, lo analizan e interpretan las instrucciones sobre la marcha. Por lo tanto, este es capaz de mantener una conversación interactiva.
Su funcionamiento es el siguiente:
- Lectura del código fuente: El intérprete recibe el código fuente escrito en el lenguaje de programación que soporta y lee el código línea por línea o en bloques.
- Análisis léxico y sintáctico: El intérprete analiza el código para identificar los tokens (elementos básicos del código como palabras clave, operadores e identificadores) y verifica que el código sigue la sintaxis correcta del lenguaje.
- Ejecución: El intérprete ejecuta las instrucciones directamente, realizando las operaciones descritas en el código fuente.
- Producción de resultados: El intérprete produce los resultados de la ejecución.
En algunos casos, el intérprete puede convertir el código fuente en código intermedio o en representación interna que facilita la ejecución después del análisis léxico y sintáctico. Este paso no es necesario en todos los intérpretes.
Ventajas
- Facilidad de uso: Permiten la ejecución y pruebas de código de forma rápida e interactiva. Ideal para desarrollo y depuración donde el desarrollador puede ejecutar y probar código en pequeños fragmentos.
- Portabilidad: El código fuente interpretado puede ejecutarse en diferentes plataformas sin necesidad de recompilar, siempre que haya un intérprete disponible para la plataforma deseada.
- Flexibilidad: Facilita la modificación y la ejecución dinámica de código. Puede ser útil en sistemas que requieren scripts o configuraciones que cambian frecuentemente.
Desventajas
- Desempeño: La ejecución puede ser más lenta en comparación con el código compilado, ya que el intérprete debe procesar e interpretar el código en tiempo real.
- Uso de recursos: La interpretación en tiempo real puede consumir más recursos, como CPU y memoria, en comparación con el código previamente compilado.
- Distribución de código: El código fuente interpretado puede ser más fácil de modificar y, por tanto, puede presentar riesgos de seguridad si se distribuye sin proteger adecuadamente.
Modelos híbridos
Los lenguajes de programación que utilizan modelos híbridos combinan compilación e interpretación en su ejecución. Esto significa que el código fuente no se transforma directamente en código máquina ni se interpreta línea a línea, sino que suele pasar primero por una compilación a un código intermedio (como el bytecode) y luego este es interpretado o ejecutado por una máquina virtual o un entorno de ejecución especializado.
El objetivo de este enfoque es lograr un equilibrio entre portabilidad y rendimiento. los lenguajes híbridos aprovechan lo mejor de ambos mundos, buscando ser eficientes, seguros y adaptables a distintos entornos de ejecución:
- La compilación previa permite detectar errores antes de ejecutar y optimizar el código.
- La interpretación o la máquina virtual facilitan la ejecución en diferentes plataformas sin necesidad de recompilar desde cero.
Java
Java es un ejemplo de lenguaje de programación que utiliza tanto un compilador como un intérprete para la ejecución del código. Este enfoque combina los mejores aspectos de la compilación y de la interpretación, permitiendo la portabilidad y la eficiencia.
El funcionamiento es el siguiente:
- Compilación en Java
- Código fuente escrito en Java: El programador escribe el código fuente en Java en ficheros
.java, que son ficheros de texto con código fuente de alto nivel. - Compilador: El compilador Java (
javac) toma el código fuente escrito en Java y lo compila a bytecode de Java (ficheros.class), que es un código intermedio e independiente de la plataforma.
- Código fuente escrito en Java: El programador escribe el código fuente en Java en ficheros
- Ejecución en Java
- Máquina Virtual de Java (JVM, Java Virtual Machine): La JVM es un intérprete que ejecuta el bytecode generado por el compilador
javac. La JVM es responsable de interpretar y ejecutar el bytecode, y está diseñada para ser multiplataforma, lo que significa que el mismo bytecode puede ejecutarse en diferentes sistemas operativos y arquitecturas de hardware, siempre que haya una JVM disponible para esa plataforma. - Interpretación y Compilación Justo a Tiempo (JIT): La JVM usa un mecanismo llamado Compilación Justo a Tiempo (JIT, Just-In-Time Compilation) para mejorar el desempeño. El JIT compila el bytecode en código de máquina nativo durante la ejecución, lo que permite una ejecución más rápida.
- Máquina Virtual de Java (JVM, Java Virtual Machine): La JVM es un intérprete que ejecuta el bytecode generado por el compilador
Este modelo híbrido aporta portabilidad, ya que el bytecode de Java puede ejecutarse en cualquier plataforma que tenga una JVM, lo que permite que el mismo código fuente funcione en distintos sistemas operativos y arquitecturas de hardware sin modificaciones. Además, ofrece seguridad, ya que el bytecode se ejecuta en un entorno controlado proporcionado por la JVM, capaz de verificar y proteger contra ciertas vulnerabilidades. También mejora el desempeño, gracias a la compilación JIT, que optimiza la ejecución del código en tiempo real y aumenta la eficiencia del programa.
Python
Aunque muchas veces se habla de Python como un lenguaje interpretado, en realidad su funcionamiento combina compilación e interpretación.
Cuando se ejecuta un programa en Python, el código fuente (contenido en ficheros .py) primero pasa por el compilador interno de CPython, que lo traduce a un bytecode. Este formato intermedio no es código máquina nativo, sino un conjunto de instrucciones específicas que se almacenan en archivos .pyc dentro de la carpeta __pycache__.
Después, ese bytecode es ejecutado por la Máquina Virtual de Python (PVM, Python Virtual Machine), el intérprete que lee e interpreta las instrucciones una a una.
Este modelo híbrido aporta portabilidad, ya que el mismo bytecode puede ejecutarse en cualquier plataforma con una PVM disponible, y flexibilidad, al permitir un modo interactivo (REPL) y facilitar la depuración.
C#
C# es un lenguaje que combina compilación e interpretación dentro de la plataforma .NET.
Cuando se escribe un programa en C#, el código fuente se procesa primero con el compilador de C# (csc), que lo traduce a un formato intermedio llamado Common Intermediate Language (CIL). Este código intermedio no es código máquina, sino una representación portable que se almacena normalmente en archivos .exe o .dll.
Después, al ejecutar el programa, entra en acción el Common Language Runtime (CLR), que funciona como intérprete de ese CIL. El CLR puede ejecutar las instrucciones de forma directa o, para ganar velocidad, usar un compilador JIT (Just-In-Time) que traduce las partes más utilizadas a código máquina nativo, optimizando el rendimiento en tiempo real.
Gracias a este modelo híbrido, C# consigue portabilidad (el mismo CIL puede ejecutarse en diferentes sistemas que tengan CLR) y eficiencia (el JIT aprovecha al máximo los recursos de la máquina).
Node.js (JavaScript)
Node.js es una plataforma para ejecutar código fuente escrito en JavaScript. No genera bytecode propio como hace, por ejemplo, Java (JVM) o C# (CLR). Lo que ocurre es lo siguiente:
Node.js está basado en V8, el motor de JavaScript de Google Chrome. Este motor no interpreta directamente el código JavaScript línea a línea, sino que primero traduce el código JavaScript a bytecode interno, usando un compilador llamado Ignition. Luego, en las partes críticas de rendimiento, V8 utiliza un compilador JIT (TurboFan) que traduce ese bytecode a código máquina nativo para ejecutarlo mucho más rápido.

Node.js (a través de V8) usa bytecode como representación intermedia, pero ese bytecode no es portable ni visible para el programador (es un formato interno del motor V8, no como el bytecode de Java que puedes distribuir y ejecutar en cualquier JVM).
Tipado
El tipado en programación es la manera en la que un lenguaje de programación clasifica y controla los distintos tipos de datos que se usan (como números, texto, verdadero/falso, etc.).
En otras palabras, cada valor que se maneja en un programa tiene un tipo (por ejemplo, 5 es un número, "hola" es texto). El tipado sirve para que el programa sepa cómo debe trabajar con esos valores y evitar errores, como intentar sumar una palabra con un número.
La clasificación de los lenguajes de programación según su tipado se refiere a cómo se manejan y restringen los tipos de datos dentro de un lenguaje. El tipado de un lenguaje puede afectar cómo se realizan las operaciones, la robustez del código y la facilidad de detección de errores. Aquí están los principales tipos de tipado en lenguajes de programación:

Tipado estático y tipado dinámico
En el tipado estático (statically typed), el tipo de cada variable y expresión es conocido y verificado en el momento de la compilación. Esto significa que los errores de tipo son detectados antes de que el programa se ejecute.
En cambio, en el tipado dinámico (dynamic typed) los tipos de datos son verificados y determinados durante la ejecución del programa. Esto significa que el tipo de una variable puede cambiar a medida que el programa se ejecuta.
Tipado débil y tipado fuerte
En el tipado débil (weak typed), el sistema de tipos permite conversiones automáticas o implícitas entre tipos de datos. Esto significa que el lenguaje puede realizar conversiones entre tipos de forma implícita, lo que puede llevar a comportamientos inesperados.
Una conversión de tipo implícita ocurre cuando el propio lenguaje de programación cambia automáticamente un dato de un tipo a otro, sin que la persona que programa tenga que pedirlo.
En cambio en el tipado fuerte (strong typed), el sistema de tipos requiere que las conversiones entre tipos sean explícitas y controladas. Las conversiones implícitas no se permiten, y las incompatibilidades de tipo son tratadas como errores.
Tipado explícito y tipado implícito
En el tipado explícito (explicitly typed), el tipo de cada variable debe ser especificado claramente por el programador en el momento de la declaración o definición.
Por otro lado, en el tipado implícito (implicitly typed), el tipo de las variables es inferido por el compilador o intérprete en función del contexto. El programador no tiene que especificar el tipo explícitamente.
Elementos comunes de la sintaxis
Aunque los lenguajes de programación pueden diferir en sintaxis y características, todos comparten algunos elementos comunes fundamentales que permiten la construcción de programas efectivos y eficientes.
A continuación se enumeran y defines los diferentes elementos comunes a todos los lenguajes de programación.
Identificadores
Son nombres definidos por el programador para representar variables, funciones, clases, etc.
Variables
Las variables son espacios en la memoria que almacenan datos y tienen un nombre asociado. Pueden contener diferentes tipos de datos, como números, cadenas de texto, u objetos más complejos.
Funciones
Las funciones son bloques de código que realizan una tarea específica y pueden ser llamadas desde otras partes del programa. Pueden recibir parámetros y devolver valores.
Palabras clave
Las palabras clave (keywords) o palabras reservadas son palabras predefinidas por el lenguaje que tienen significados especiales y no pueden ser usadas como identificadores.
Por ejemplo, palabras clave del lenguaje C son las siguientes:
auto
break
case
char
const
continuar
default
do
double
else
enum
extern
float
para
goto
si
int
long
register
return
short
signed
sizeof
static
struct
switch
typedef
union
unsigned
void
volátil
while
Delimitadores y separadores
Son caracteres que se usan para estructurar el código y separar diferentes partes del mismo. Incluyen paréntesis, corchetes, llaves, punto y coma, comas, etc.
Tipos de datos
Los tipos de datos definen el tipo de datos que una variable puede almacenar.
El tipo influirá en el espacio de memoria que se necesitará para almacenar un dato de ese tipo y la clase de dato que se podrá guardar en ese espacio. Por ejemplo, no se necesita el mismo espacio para guardar un número que para guardar un texto.
Los tipos de datos comunes incluyen:
- Enteros (integer) Números enteros.
- Flotantes (float): Números con decimales.
- Cadenas de texto (string): Secuencias de caracteres.
- Booleanos (boolean): Valores verdaderos o falsos.
- Estructuras de datos: Los lenguajes de programación permiten almacenar y manipular colecciones de datos usando diferentes estructuras, como:
- Arrays o vectores (array): Colecciones de elementos del mismo tipo.
- Listas (list): Colecciones dinámicas que permiten elementos de diferentes tipos.
- Mapas o diccionarios (map): Pares clave-valor.
Cada lenguaje de programación define sus tipos. Se deben consultar las especificaciones de cada lenguaje.
Operadores
Los operadores se utilizan sobre variables y valores para realizar diferentes tipos de operaciones. Hay diferentes categorías de operadores:
- Aritméticos (
+,-,*,/,%): Realizan operaciones matemáticas básicas. - De comparación (
==,!=,>,<,>=,<=): Comparan dos valores. - Lógicos (
&&,||,!): Realizan operaciones lógicas.
Estructuras de control
Las estructuras de control permiten cambiar el flujo de ejecución del programa basándose en condiciones o repeticiones. Las principales estructuras de control incluyen:
- Condicionales: Ejecutan bloques de código basados en condiciones.
- Bucles: Repiten un bloque de código varias veces.
Entrada y salida (I/O)
Los programas necesitan interactuar con el mundo exterior a través de la entrada y salida de datos. Esto incluye leer datos del usuario, archivos, o enviar datos a una pantalla o archivo. A este proceso se le conoce como I/O, que son las siglas en inglés de Input/Output (entrada/salida). El término proviene de la informática y la electrónica, donde se usa para describir cómo un sistema recibe información (input) y cómo la transmite o muestra (output).
Como dato curioso, Google bautizó con el nombre I/O a sus conferencias anuales para desarrolladores, inspirándose en este concepto.
Comentarios
Los comentarios son anotaciones en el código que no son ejecutadas, usadas para explicar el código o dejar notas. Pueden ser de una sola línea o de varias líneas.