Por que o Python precisa de um compilador e um intérprete?

9

Eu posso entender o fato de que o Java precisa de um compilador e um intérprete. Ele compila o código-fonte no bytecode e, em seguida, uma máquina virtual (no Windows, no Linux, no Android etc.) converte esse bytecode em código de máquina para a arquitetura atual.

Mas por que o Python precisa de um compilador e um intérprete? Como o Python não é independente de plataforma, por que não usar apenas interpretação? Tanto quanto eu sei, você não pode executar um programa Python (compilado em bytecode) em qualquer máquina Windows ou Linux sem modificação. Ou eu estou errado?

aris
fonte
Você pode estar errado. Se você usar Lua em vez de Python, você estará errado.
Basile Starynkevitch

Respostas:

13

Até onde eu sei, você não pode executar um programa Python (compilado em bytecode) em todas as máquinas, como no Windows ou no Linux sem modificação.

Você está incorreto. O bytecode python é multiplataforma. Consulte Python bytecode depende da versão? Depende da plataforma? no estouro de pilha. No entanto, não é compatível entre versões. O Python 2.6 não pode executar arquivos do Python 2.5. Portanto, apesar da plataforma cruzada, geralmente não é útil como formato de distribuição.

Mas por que o Python precisa de um compilador e um intérprete?

Rapidez. A interpretação estrita é lenta. Praticamente toda linguagem "interpretada" compila o código-fonte em algum tipo de representação interna, para que não precise analisar repetidamente o código. No caso do python, ele salva essa representação interna em disco para que possa pular o processo de análise / compilação na próxima vez que precisar do código.

Winston Ewert
fonte
7

Eu posso entender o fato de que o Java precisa de um compilador e um intérprete.

Não faz. Não há nada na Java Language Specification que diga que o Java precisa ter um compilador. Também não há nada na Especificação de Linguagem Java que diga que o Java precisa ter um intérprete.

A utilização de um intérprete, um compilador ou uma combinação dos dois é deixada completamente a critério do implementador.

Na verdade, não são implementações de Java que compilam diretamente para código de máquina, por exemplo, o GNU Compiler para Java gcj. Tecnicamente falando, o compilador Oracle OpenJDK Java também compila para o código da máquina, especificamente, o código de bytes da JVM. Agora, você pode dizer, espere um minuto, isso não é código de máquina! Porém, existem intérpretes de software para o código de máquina x86 e existem CPUs de hardware que podem executar o código de bytes da JVM, então o que torna um "nativo" e o outro não?

Observe que o código de bytes da JVM fica fora da Java Language Specification, assim como o código de máquina x86.

e então uma máquina virtual (no Windows, no Linux, no Android etc.) converte esse bytecode em código de máquina para a arquitetura atual.

Novamente, isso depende exclusivamente do implementador.

A Sun JVM original nunca traduziu, sempre interpretou. O Oracle OpenJDK JVM atual interpreta e apenas as partes que são executadas com freqüência são compiladas. A VM da Maxine Research sempre compila o JIT. A implementação do Excelsior.JET é compilada uma vez, com antecedência. A JVM do IKVM.NET é compilada no código de bytes CIL. O Android Runtime compila antecipadamente, uma vez, durante a instalação. (Além disso, o Android Runtime não entende o código de byte da JVM, ele usa o código de byte Dalvik, que é um idioma completamente diferente.)

Mas por que o Python precisa de um compilador e um intérprete?

Novamente, não. Não há nada na especificação da linguagem Python que diga que o Python precisa ter um compilador. Também não há nada na especificação da linguagem Python que diga que o Python precisa abrigar um intérprete.

Observe que, na verdade, Python nunca é interpretado. Toda a implementação existente do Python sempre compila o Python para um idioma diferente. Essa linguagem pode ou não ser interpretada, por sua vez, mas é uma linguagem diferente do Python. Python não é interpretado.

por que não usar apenas interpretação?

Porque o Python não foi projetado para ser facilmente interpretado por máquinas. Ele é projetado para ser facilmente interpretado por seres humanos. OTOH, código de bytes CPython, é projetado para ser facilmente interpretado por máquinas. Portanto, faz sentido escrever código em uma linguagem projetada para humanos e interpretar em uma linguagem projetada para máquinas e, para passar de uma para a outra, você precisa compilar.

Tanto quanto eu sei, você não pode executar um programa Python (compilado em bytecode) em qualquer máquina Windows ou Linux sem modificação.

Sim você pode. A VM do CPython está disponível para Windows e Linux, assim como PyPy, Jython e IronPython.


Os idiomas não precisam ser compilados ou interpretados. Idiomas são apenas . De fato, uma linguagem pode existir perfeitamente sem ter nenhum intérprete ou compilador! Por exemplo, o Plankalkül de Konrad Zuse, que ele projetou na década de 1930, nunca foi implementado durante sua vida. Você ainda pode escrever programas nele, analisar esses programas, argumentar sobre eles, provar propriedades sobre eles ... você simplesmente não pode executá-los. (Bem, na verdade, mesmo isso está errado: é claro que você pode executá-los na cabeça ou com caneta e papel.)

Agora, qualquer implementação específica de uma linguagem pode usar um compilador (ou até vários compiladores), um intérprete ou qualquer combinação. Mas essa é uma característica da implementação , não a linguagem. Todo idioma pode ser implementado com um compilador e todo idioma pode ser implementado com um intérprete.

Observe, no entanto, que você não pode executar um programa sem um intérprete. Um compilador simplesmente traduz um programa de um idioma para outro. Mas é isso. Agora você tem o mesmo programa, apenas em um idioma diferente. A única maneira de obter um resultado do programa é interpretá- lo. Às vezes, a linguagem é uma linguagem de máquina binária extremamente simples, e o intérprete é realmente codificado em silicone (e chamamos de "CPU"), mas isso ainda é interpretação.

Você também pode estar interessado nesta resposta minha, que explica as diferenças e os diferentes meios de combinar intérpretes, compiladores JIT e compiladores AOT e esta resposta que trata das diferenças entre um compilador AOT e um compilador JIT .

Jörg W Mittag
fonte
3
As respostas que passam a maior parte do tempo sendo pedantes em vez de responder à pergunta me entristecem.
Winston Ewert
3

É verdade que o bytecode não é adequado como formato de distribuição, mas isso não significa que seja inútil. Além de melhorar o tempo de inicialização em uma determinada máquina, após a primeira execução, interpretar o bytecode também é muito mais simples do que interpretar um AST ou, se Deus permitir, interpretar linha por linha.

Bytecode é uma representação do código de nível mais baixo, mais regular e mais compacta (semântica e em termos de layout de memória). A ordem das operações já está definida, os nomes das variáveis ​​locais foram resolvidos para um formato mais simples (índices inteiros). Nenhuma sintaxe complicada a seguir, apenas uma instrução simples após a outra. Além disso, é necessário menos estado: para a interpretação linha a linha, você basicamente precisa manter um analisador inteiro por perto, e um intérprete AST explode a pilha de chamadas com sua passagem em árvore, enquanto um interpretador de bytecode precisa apenas de uma pequena pilha para valores temporários e locais.

Esses e outros fatores conspiram para tornar os intérpretes de bytecode significativamente mais rápidos do que outros intérpretes.


fonte