Perché Python ha bisogno sia di un compilatore che di un interprete?

8

Posso capire il fatto che Java abbia bisogno sia di un compilatore che di un interprete. Compila il codice sorgente in bytecode e quindi una macchina virtuale (su Windows, su Linux, su Android, ecc.) Traduce quel codice bytecode in codice macchina per l'architettura corrente.

Ma perché Python ha bisogno sia di un compilatore che di un interprete? Poichè Python non è indipendente dalla piattaforma, perché non usare solo l'interpretazione? Per quanto ne so, non è possibile eseguire un programma Python (compilato in bytecode) su nessuna macchina Windows o Linux senza modifiche. O mi sbaglio?

    
posta aris 11.07.2015 - 17:06
fonte

3 risposte

12

As far as I know, you cannot execute a Python program (compiled to bytecode) on every machine, such as on windows, or on linux without modification.

Non sei corretto. Il bytecode python è multipiattaforma. Vedi È dipendente dalla versione bytecode python? È dipendente dalla piattaforma? su Stack Overflow. Tuttavia, non è compatibile tra le versioni. Python 2.6 non può eseguire file Python 2.5. Quindi, anche se multipiattaforma, non è generalmente utile come formato di distribuzione.

But why Python needs both a compiler and an interpreter?

Velocità. L'interpretazione rigorosa è lenta. Praticamente ogni linguaggio "interpretato" in realtà compila il codice sorgente in una sorta di rappresentazione interna in modo che non debba analizzare ripetutamente il codice. Nel caso di Python salva questa rappresentazione interna sul disco in modo che possa saltare il processo di parsing / compiling la prossima volta che ha bisogno del codice.

    
risposta data 11.07.2015 - 17:21
fonte
5

I can understand the fact that Java needs both a compiler and an interpreter.

Non è così. Non c'è nulla nella specifica del linguaggio Java che dice che Java ha bisogno di avere un compilatore. Non c'è anche nulla nella specifica del linguaggio Java che dice che Java ha bisogno di avere un interprete.

Se utilizzare un interprete, un compilatore o una combinazione dei due, è completamente lasciato alla discrezione dell'implementatore.

In effetti, là sono implementazioni di Java che compilano direttamente il codice macchina, ad es. il compilatore GNU per Java gcj . Tecnicamente parlando, il compilatore Java Oracle OpenJDK viene compilato anche per codice macchina, in particolare codice byte JVM. Ora, potresti dire, aspetta un attimo, non è un codice macchina! Ma ci sono interpreti software per il codice macchina x86 e ci sono CPU hardware che possono eseguire codice byte JVM, quindi cosa rende un "nativo" e l'altro no?

Si noti che il codice byte JVM si trova all'esterno delle specifiche della lingua Java, proprio come fa il codice macchina x86.

and then a virtual machine (on Windows, on Linux, on Android, etc.) translates that bytecode to machine code for the current architecture.

Di nuovo, è puramente fino all'implementatore.

L'originale Sun JVM non ha mai tradotto, sempre interpretato. L'attuale Oracle OpenJDK JVM interpreta e solo quelle parti che vengono eseguite spesso vengono compilate. Maxine Research VM compila sempre JIT. L'implementazione Excelsior.JET viene compilata una volta, in anticipo. La JVM IKVM.NET viene compilata con il codice byte CIL. Android Runtime viene compilato in anticipo, una volta, durante l'installazione. (Inoltre, Android Runtime non capisce il codice byte JVM, utilizza il codice byte Dalvik, che è una lingua completamente diversa.)

But why does Python need both a compiler and an interpreter?

Ancora, non è così. Non c'è nulla nella specifica del linguaggio Python che dice che Python deve avere un compilatore. Non c'è anche nulla nella specifica del linguaggio Python che dice che Python deve avere un interprete.

Si noti che in realtà, Python è mai interpretato. Tutta l'implementazione esistente di Python sempre compila Python in una lingua diversa. Quella lingua può o meno essere interpretata, a sua volta, ma quella lingua è una lingua diversa da Python. Python non viene interpretato.

why not just use interpretation?

Perché Python non è progettato per essere facilmente interpretato dalle macchine. È progettato per essere facilmente interpretato dall'uomo. OTOH, codice byte CPython, è progettato per essere facilmente interpretato dalle macchine. Quindi, ha senso scrivere write in un linguaggio progettato per gli umani e interpretare in un linguaggio progettato per le macchine, e per poter passare dall'uno all'altro, devi compilazione.

As far as I know, you cannot execute a Python program (compiled to bytecode) on any Windows or Linux machine without modification.

Sì, puoi. La VM CPython è disponibile per Windows e Linux, come PyPy, Jython e IronPython.

Le lingue non devono essere compilate o interpretate. Le lingue solo sono . In effetti, un linguaggio può perfettamente esistere senza avere qualsiasi interprete o compilatore! Ad esempio, il Plankalkül di Konrad Zuse, progettato negli anni '30, non è mai stato implementato durante la sua vita. Potresti ancora scrivere programmi in esso, puoi analizzare quei programmi, ragionare su di loro, dimostrarne le proprietà ... non puoi semplicemente eseguirli. (Beh, in realtà, anche questo è sbagliato: puoi ovviamente eseguirli nella tua testa o con carta e penna.)

Ora, qualsiasi particolare implementazione di una lingua può usare un compilatore (o anche più compilatori), un interprete o qualsiasi combinazione. Ma questa è una caratteristica dell'implementazione , non della lingua. Ogni lingua può essere implementata con un compilatore e ogni lingua può essere implementata con un interprete.

Si noti, tuttavia, che non è possibile eseguire un programma senza un interprete. Un compilatore traduce semplicemente un programma da una lingua all'altra. Ma è così. Ora hai lo stesso programma, solo in una lingua diversa. Il solo modo per ottenere effettivamente un risultato del programma è quello di interpretarlo . A volte, il linguaggio è un linguaggio di macchina binaria estremamente semplice, e l'interprete è in realtà hardcoded in silicone (e lo chiamiamo "CPU"), ma è comunque un'interpretazione.

Potresti anche essere interessato a questa mia risposta, che spiega le differenze e i diversi mezzi per combinare gli interpreti, i compilatori JIT e compilatori AOT e questa risposta si occupa delle differenze tra un compilatore AOT e un compilatore JIT .

    
risposta data 12.07.2015 - 03:28
fonte
3

È vero che il bytecode non è adatto come formato di distribuzione, ma ciò non significa che sia inutile. A parte il miglioramento del tempo di avvio su una determinata macchina, dopo la prima esecuzione, interpretare il bytecode è anche molto più semplice dell'interpretazione di un AST o, dio non voglia, dell'interpretazione riga per riga.

Il codice byte è una rappresentazione più a basso livello, più regolare, più compatta (sia semanticamente che in termini di layout di memoria) del codice. L'ordine delle operazioni è già spiegato, i nomi delle variabili locali sono stati risolti in una forma più semplice (indici interi). Nessuna sintassi complicata da seguire, solo una semplice istruzione dopo l'altra. Inoltre, è necessario uno stato inferiore: per l'interpretazione riga per riga è fondamentalmente necessario mantenere un intero parser e un interprete AST fa esplodere lo stack di chiamate con il suo attraversamento dell'albero, mentre un interprete bytecode ha solo bisogno di un piccolo stack per i valori temporanei e locali.

Questi e altri fattori contribuiscono a rendere gli interpreti bytecode molto più veloci di altri interpreti.

    
risposta data 11.07.2015 - 17:19
fonte

Leggi altre domande sui tag