Ingeniería en Desarrollo de Software y Tecnologías Emergentes — Plan 2021-2
Paradigmas de Programación · Grupo 544, Subgrupo 0 · Dr. Jose Manuel Muñoz Contreras
Del código que escribes
al código que corre
Entre tu editor de texto y la pantalla que muestra el resultado hay un proceso invisible: alguien tiene que traducir lo que escribiste a algo que el hardware entienda. Dos estrategias compiten por ese trabajo — compilar y interpretar — y esta nota te lleva paso a paso por ambas.
Traducir no es lo mismo que ejecutar
Ya viste que un lenguaje se puede analizar en cuatro niveles: léxico, sintáctico, semántico y pragmático (1.2.1–1.2.3). Ese análisis responde qué significa el programa. Pero falta una pregunta distinta: una vez que el programa es válido, ¿cómo llega a ejecutarse sobre el hardware real?
Traducir es convertir el código fuente a otra representación (código máquina, bytecode, etc.). Ejecutar es llevar a cabo esas instrucciones sobre un procesador, real o virtual. Un compilador y un intérprete son las dos estrategias clásicas para combinar ambas tareas — y difieren, sobre todo, en cuándo ocurre la traducción respecto a la ejecución.
¿Qué es un compilador?
Un compilador traduce todo el programa antes de que se ejecute una sola instrucción. Lee el código fuente completo, lo analiza en varias fases sucesivas, y al final entrega un archivo ejecutable independiente. Ejemplos: C, C++, Rust, Go, Haskell (GHC).
total = precio * cantidad + descuento avanza por cada etapa del compilador.
El resultado final —código máquina o un ejecutable— corre directamente sobre el hardware, sin que el compilador intervenga de nuevo. Por eso los programas compilados suelen arrancar y correr más rápido: todo el trabajo de traducción ya se pagó de antemano.
¿Qué es un intérprete?
Un intérprete no genera un ejecutable aparte: lee y ejecuta el código fuente línea por línea, en el momento. No hay una fase de "traducir todo primero" — traducir y ejecutar ocurren entrelazados. Ejemplos: Python (CPython), Ruby, PHP.
Comparativa: compilador vs. intérprete
Ninguno es "mejor" en abstracto — cada uno optimiza para prioridades distintas. La tabla resume las diferencias que más importan al elegir un lenguaje para un proyecto real.
| Criterio | Compilador | Intérprete |
|---|---|---|
| Momento de traducción | Antes de ejecutar, una sola vez | Durante la ejecución, cada vez |
| Velocidad de ejecución | Generalmente mayor | Generalmente menor |
| Detección de errores | En tiempo de compilación | Hasta que la línea se ejecuta |
| Portabilidad del código fuente | Depende del destino (salvo bytecode) | Alta — corre donde haya intérprete |
| Ciclo de desarrollo | Compilar → ejecutar (más lento por iteración) | Ejecutar directo (iteración rápida) |
| Ejemplos representativos | C, C++, Rust, Go | Python (CPython, que antes compila a bytecode), Ruby, PHP — la estrategia es propiedad de la implementación, no del lenguaje |
Conviene compilar cuando…
- Se necesita máximo rendimiento en producción (sistemas embebidos, videojuegos, cómputo de alto desempeño)
- El entorno de despliegue es estable y conocido
- Se quiere detectar errores antes de entregar el software al usuario final
Conviene interpretar cuando…
- Se prioriza velocidad de desarrollo e iteración (prototipado, scripting)
- Se necesita portabilidad sin recompilar para cada sistema operativo
- Se trabaja en entornos interactivos (REPL, notebooks, exploración de datos)
El caso híbrido: máquinas virtuales
La distinción compilador/intérprete no siempre es tajante. Muchos lenguajes modernos usan una estrategia mixta: compilan a un código intermedio portable (bytecode) que luego una máquina virtual interpreta o compila JIT en tiempo de ejecución.
.javajavac.classintérprete + JIT
| Lenguaje | Compila a | Ejecuta con |
|---|---|---|
| Java | javac → bytecode .class | JVM (intérprete + JIT HotSpot) |
| C# | CIL (Common Intermediate Language) | CLR (.NET) |
| Python | bytecode .pyc | Máquina virtual de CPython |
Práctica: clasifica el lenguaje
Para cada lenguaje, decide si su estrategia principal es compilado, interpretado o híbrido (bytecode + máquina virtual / JIT). Recibirás retroalimentación inmediata.
Lo esencial de 1.2.4
Compiladores e intérpretes son dos estrategias para resolver el mismo problema —llevar el código fuente a ejecución— con compromisos distintos entre velocidad, portabilidad y ciclo de desarrollo. La mayoría del software real que usas hoy vive en algún punto intermedio del espectro, combinando ambas ideas.
Compilar = traducir todo antes de ejecutar. Interpretar = traducir y ejecutar entrelazados, línea por línea. Híbrido = compilar a un código intermedio portable que una máquina virtual interpreta o compila JIT.
Preguntas de reflexión
- ¿En qué escenarios conviene un intérprete sobre un compilador, y viceversa?
- ¿Cómo afecta la estrategia de traducción/ejecución elegida a la relación entre el desarrollador y los errores de su programa?
- ¿Qué papel juega el enfoque híbrido (bytecode + JIT) en el diseño de lenguajes modernos?