Un lenguaje de programación interpretado es un lenguaje de programación cuyo código fuente es ejecutado por el método de interpretación [1] . Al clasificar los lenguajes de programación según el método de ejecución [2] , el grupo de lenguajes interpretados incluye lenguajes en los que las declaraciones del programa, una tras otra, se traducen por separado y se ejecutan (interpretan) inmediatamente [3] utilizando un programa de interpretación especial (que se opone [1] a los lenguajes compilados , en los que todas las instrucciones del programa se traducen de antemano en código objeto [3]). Dicho lenguaje puede implementar construcciones que permitan cambios dinámicos en tiempo de ejecución (modificación de subrutinas existentes o creación de nuevas). Estas construcciones dificultan la compilación y la traducción a un lenguaje compilado [1] .
En general, cualquier lenguaje puede ser compilado e interpretado. En el caso límite, tal lenguaje puede implementarse solo con la ayuda de intérpretes [4] . También existen los nombres lenguaje interpretativo (“interpretable”) [4] , lenguaje interpretable (“interpretable”), lenguaje interpretado (“interpretable”) [5] .
Sin embargo, para muchos idiomas existe una diferencia de rendimiento entre las implementaciones compiladas e interpretadas.
Una gran cantidad de lenguajes, incluidos BASIC , C , Lisp , Pascal y Python , tienen ambas implementaciones. Java utiliza la compilación JIT para generar código nativo, aunque inicialmente se traduce a una forma interpretada. Los lenguajes de Microsoft .NET Framework se compilan en Common Intermediate Language (CIL) , que se compila en código nativo en tiempo de ejecución. La mayoría de las implementaciones de Lisp te permiten mezclar ambos tipos de código.
En los primeros días de la programación, los lenguajes estaban fuertemente influenciados por la forma en que se ejecutaban. Por ejemplo, los lenguajes compilados requerían que el tipo de datos de una variable se especificara en el momento en que se declaró o utilizó por primera vez. Mientras que los lenguajes interpretados, por su naturaleza dinámica, permitieron abandonar este requisito, lo que dio más flexibilidad y desarrollo acelerado.
Inicialmente, los lenguajes interpretados se convertían a código máquina línea por línea, es decir, cada línea lógica se compilaba justo antes de la ejecución. Como resultado, cada instrucción encerrada en el cuerpo del ciclo y ejecutada varias veces fue procesada por el compilador la misma cantidad de veces. En la actualidad, tales efectos son raros. La mayoría de los idiomas interpretados están pretraducidos a una representación intermedia. Es un bytecode o código de hilos . Este es un conjunto de instrucciones para llamar a pequeños fragmentos de código de nivel inferior, equivalentes a varias instrucciones de ensamblador o instrucciones de máquina virtual , respectivamente. Este código ya lo ejecuta un intérprete o una máquina virtual. Por ejemplo, Java , Python y Ruby utilizan un esquema de este tipo (utiliza la representación del código en forma de un árbol de sintaxis abstracta ).
El código intermedio se puede crear compilando explícitamente todo el proyecto (Java) o mediante traducción implícita cada vez que se inicia el programa (Perl, Ruby) y cuando cambia el código fuente (Python).
Hay una serie de características que son mucho más fáciles de implementar en un intérprete que en un compilador:
Además, los principios y el estilo de programación a menudo no requieren la creación y descripción de construcciones especiales que dan forma al programa (manifiestos, clases, tipos de datos). Esto le permite desarrollar y probar el código de forma incremental, lo cual es útil tanto para escribir programas pequeños como para el desarrollo de módulos aislados para sistemas complejos. Debido a su versatilidad, son convenientes para usar como lenguajes de scripting .
La eliminación del paso de compilación permite un desarrollo más rápido de los programas, por lo que se utilizan lenguajes interpretados al escribir programas complejos de una sola vez (por ejemplo, para realizar un cálculo de una sola vez).
La principal desventaja es la ejecución más lenta del programa [1] [6] [7] en comparación con la ejecución de un programa precompilado en código máquina . Por ejemplo, PHP y Python pueden ser 100 veces más lentos que C++ [8] . La traducción a bytecode y la compilación JIT no resuelven completamente este problema. Un intérprete adicional o una capa de máquina virtual ralentiza la ejecución del programa y puede requerir más recursos. En tiempo de ejecución, el intérprete siempre debe cargarse en la memoria (que pueden ser programas grandes, como un navegador para JS u Office para VBA) [6] . Los comentarios pueden reducir el rendimiento y, para evitar esto, se crean dos versiones del código: listas para usar (con los comentarios eliminados) y desarrolladas [9] .
Como resultado, en promedio, el código interpretado debe probarse más a fondo que el código compilado, se debe cumplir más estrictamente con las convenciones de codificación y deben usarse analizadores de calidad de código adicionales. El último inconveniente no es muy pronunciado, ya que un desarrollo serio en lenguajes compilados también requiere el uso de estas herramientas.