¿Por qué Python necesita un compilador y un intérprete?

9

Puedo entender el hecho de que Java necesita tanto un compilador como un intérprete. Compila el código fuente en bytecode y luego una máquina virtual (en Windows, en Linux, en Android, etc.) traduce ese bytecode en código de máquina para la arquitectura actual.

Pero, ¿por qué Python necesita un compilador y un intérprete? Dado que Python no es independiente de la plataforma, ¿por qué no solo usar la interpretación? Hasta donde yo sé, no puede ejecutar un programa Python (compilado en bytecode) en ninguna máquina Windows o Linux sin modificación. ¿O estoy equivocado?

aris
fuente
Podrías estar equivocado. Si usa Lua en lugar de Python, estaría equivocado.
Basile Starynkevitch

Respuestas:

13

Hasta donde sé, no puede ejecutar un programa Python (compilado en bytecode) en todas las máquinas, como en Windows o Linux sin modificaciones.

Eres incorrecto El código de bytes de Python es multiplataforma. Consulte ¿El código de bytes de Python depende de la versión? ¿Depende de la plataforma? en desbordamiento de pila. Sin embargo, no es compatible entre versiones. Python 2.6 no puede ejecutar archivos Python 2.5. Entonces, aunque es multiplataforma, generalmente no es útil como formato de distribución.

Pero, ¿por qué Python necesita un compilador y un intérprete?

Velocidad. La interpretación estricta es lenta. Prácticamente cada lenguaje "interpretado" en realidad compila el código fuente en algún tipo de representación interna para que no tenga que analizar el código repetidamente. En el caso de Python, guarda esta representación interna en el disco para que pueda omitir el proceso de análisis / compilación la próxima vez que necesite el código.

Winston Ewert
fuente
7

Puedo entender el hecho de que Java necesita tanto un compilador como un intérprete.

No lo hace. No hay nada en la Especificación del lenguaje Java que diga que Java necesita tener un compilador. Tampoco hay nada en la Especificación del lenguaje Java que diga que Java necesita tener un intérprete.

Si se debe usar un intérprete, un compilador o una combinación de ambos, queda completamente a discreción del implementador.

De hecho, no son implementaciones de Java, que compilan directamente a código de máquina, por ejemplo, el compilador de GNU para Java gcj. Técnicamente hablando, el compilador Oracle OpenJDK Java también compila en código máquina, específicamente, código de bytes JVM. Ahora, usted podría decir, ¡espere un minuto, eso no es código de máquina! Pero, hay intérpretes de software para el código de máquina x86, y hay CPU de hardware que pueden ejecutar el código de bytes JVM, entonces, ¿qué hace que uno sea "nativo" y el otro no?

Tenga en cuenta que el código de bytes JVM se encuentra fuera de la especificación del lenguaje Java, al igual que el código de máquina x86.

y luego una máquina virtual (en Windows, en Linux, en Android, etc.) traduce ese bytecode a código de máquina para la arquitectura actual.

Nuevamente, eso depende exclusivamente del implementador.

El Sun JVM original nunca tradujo, siempre interpretó. El Oracle OpenJDK JVM actual interpreta, y solo las partes que se ejecutan a menudo se compilan. Maxine Research VM siempre compila JIT. La implementación Excelsior.JET se compila una vez, con anticipación. IKVM.NET JVM compila en código de bytes CIL. Android Runtime compila con anticipación, una vez, durante la instalación. (Además, Android Runtime no comprende el código de bytes JVM, utiliza el código de bytes Dalvik, que es un lenguaje completamente diferente).

Pero, ¿por qué Python necesita un compilador y un intérprete?

De nuevo, no lo hace. No hay nada en la especificación del lenguaje Python que diga que Python necesita tener un compilador. Tampoco hay nada en la especificación del lenguaje Python que diga que Python necesita tener un intérprete.

Tenga en cuenta que, en realidad, Python nunca se interpreta. Todas las implementaciones de Python existentes siempre compilan Python en un idioma diferente. Ese lenguaje puede o no, a su vez, ser interpretado, pero ese lenguaje es un lenguaje diferente al de Python. Python no se interpreta.

¿Por qué no simplemente usar la interpretación?

Porque Python no está diseñado para que las máquinas lo interpreten fácilmente. Está diseñado para ser fácilmente interpretado por humanos. OTOH, código de byte CPython, está diseñado para que las máquinas lo interpreten fácilmente. Por lo tanto, tiene sentido escribir código en un lenguaje diseñado para humanos e interpretar en un lenguaje diseñado para máquinas, y para pasar de uno a otro, debe compilar.

Hasta donde yo sé, no puede ejecutar un programa Python (compilado en bytecode) en ninguna máquina Windows o Linux sin modificación.

Sí tu puedes. CPython VM está disponible para Windows y Linux, al igual que PyPy, Jython y IronPython.


Los idiomas no tienen que ser compilados o interpretados. Los idiomas simplemente son . De hecho, ¡un lenguaje puede existir perfectamente sin tener ningún intérprete o compilador! Por ejemplo, el Plankalkül de Konrad Zuse que diseñó en la década de 1930 nunca se implementó durante su vida. Aún podría escribir programas en él, podría analizar esos programas, razonar sobre ellos, probar propiedades sobre ellos ... simplemente no podría ejecutarlos. (Bueno, en realidad, incluso eso está mal: por supuesto, puede ejecutarlos en su cabeza o con lápiz y papel).

Ahora, cualquier implementación particular de un lenguaje puede usar un compilador (o incluso múltiples compiladores), un intérprete o cualquier combinación. Pero ese es un rasgo de la implementación , no el lenguaje. Cada idioma puede implementarse con un compilador, y cada idioma puede implementarse con un intérprete.

Sin embargo, tenga en cuenta que no puede ejecutar un programa sin un intérprete. Un compilador simplemente traduce un programa de un idioma a otro. Pero eso es todo. Ahora tiene el mismo programa, solo que en un idioma diferente. La única forma de obtener un resultado del programa es interpretándolo . A veces, el lenguaje es un lenguaje de máquina binario extremadamente simple, y el intérprete está realmente codificado en silicona (y lo llamamos una "CPU"), pero eso sigue siendo interpretación.

También podría estar interesado en esta respuesta mía, que explica las diferencias y los diferentes medios de combinar intérpretes, compiladores JIT y compiladores AOT y esta respuesta trata sobre las diferencias entre un compilador AOT y un compilador JIT .

Jörg W Mittag
fuente
3
Las respuestas que pasan la mayor parte de su tiempo siendo pedantes en lugar de responder la pregunta me ponen triste.
Winston Ewert
3

Es cierto que el código de bytes no es adecuado como formato de distribución, pero eso no significa que sea inútil. Además de mejorar el tiempo de inicio en una máquina determinada, después de la primera ejecución, interpretar el código de bytes también es mucho más simple que interpretar un AST o, Dios no lo quiera, interpretar línea por línea.

Bytecode es una representación del código más baja, más regular, más compacta (tanto semánticamente como en términos de diseño de memoria). El orden de las operaciones ya está detallado, los nombres de las variables locales se han resuelto en una forma más simple (índices enteros). No hay que seguir una sintaxis complicada, solo una instrucción simple tras otra. Además, se necesita menos estado: para la interpretación línea por línea, básicamente necesita mantener un analizador completo, y un intérprete AST explota la pila de llamadas con su recorrido en árbol, mientras que un intérprete de código de bytes solo necesita una pequeña pila para valores temporales. y locales.

Estos y otros factores conspiran para hacer que los intérpretes de bytecode sean significativamente más rápidos que otros intérpretes.


fuente