È possibile compilare ogni lingua? E ogni lingua può essere interpretata? [duplicare]

3

Mi chiedevo se tutte le lingue interpretate possono essere compilate? E ogni linguaggio compilato può essere interpretato?

    
posta wannik 10.11.2014 - 05:47
fonte

4 risposte

4

Ogni lingua possibile deve supportare sia la compilazione che l'interpretazione per definizione

Il trucco sta nei significati sottostanti dell'idea di "compilazione" e "interpretazione".

L'interpretazione è "prendi questo programma scritto nel linguaggio X e crea un processo che applica le regole del linguaggio X al programma." È un modo elegante per dire che "l'interpretazione sta eseguendo il programma".

Compilare è prendere questo programma scritto in linguaggio X e scrivere un nuovo programma in linguaggio Y che, se interpretato, creerebbe gli stessi risultati dell'interpretazione diretta del programma in X. È un'operazione di mappatura da una lingua all'altra. È un modo elegante per dire "prenditi del tempo per creare un programma che, in un secondo momento, possa fare ciò che ho scritto, ma più velocemente."

Ogni lingua può essere associata a un'altra lingua. In caso contrario, la lingua non può realmente funzionare sui computer. Quindi ogni lingua può essere tecnicamente compilata. E, dato che qualsiasi programma compilato può essere scritto nella forma "interpreta l'atto di compilazione del programma, quindi interpreta il risultato", ogni programma può essere interpretato anche.

La linea è ancora sfocata con il montaggio. Si presuppone che il codice x86 sia interpretato, perché il lavoro di una CPU è quello di interpretare le tue istruzioni. Tuttavia, in realtà, x86 è troppo lento se interpretato letteralmente. Invece, ogni CPU moderna compilerà x86 nel proprio microcodice "nativo". Ciò significa che letteralmente ogni lingua "interpretata" viene compilata ad un certo punto.

Alcune lingue sono difficili da compilare o interpretare

Alcune lingue non si prestano bene alla compilazione o all'interpretazione. Un'aspettativa di un "buon" linguaggio è la velocità. Le lingue lente tendono ad essere meno desiderabili delle lingue veloci. Il C ++ ha regole che sfruttano il fatto che è tradizionalmente compilato piuttosto che interpretato. Ha regole molto lente (come la risoluzione dell'overload delle funzioni) che i compilatori possono utilizzare in un assemblaggio molto veloce (con semplici regole veloci). Un naiive interprete C ++ impiegherebbe molto tempo a ripetere queste regole lente.

Allo stesso modo, alcune lingue non si prestano bene alla compilazione. Python, per esempio, si affida alla tipizzazione delle anatre per tutto. Queste regole sono molto più veloci delle regole di compilazione di C ++, ma più lente delle regole di assemblaggio. Compilare Python non ti comprerebbe molto perché non potresti mappare Python in qualcosa di molto più semplice.

... o potresti?

Se guardi PyPy, Psyco o IronPython, c'è un tentativo di compilare Python. Fanno tecniche note come Just in Time Compiling (JIT) per trovare bit di Python che ricompensano la compilazione. Compilano quelle parti, mentre interpretano le parti che sono difficili da compilare. In molti casi che si verificano comunemente, il risultato dell'utilizzo di codice Python da IronPython a JIT è veloce o più veloce di C ++ o C #!

Questo mostra quanto sia sfocata la linea tra compilato e interpretato.

    
risposta data 10.11.2014 - 08:16
fonte
3

Sì. Come esempio banale possiamo interpretare ogni linguaggio compilato facendo in modo che l'interprete interpreti l'assembly o qualunque sia il risultato compilato. Dualmente, possiamo raggruppare l'intero interprete + il programma in un eseguibile dando un risultato "compilato".

Non hai detto "compilato bene":)

    
risposta data 10.11.2014 - 06:04
fonte
1

Dipende dalle tue definizioni di interpretato e compilato.

Ad esempio, ricordo che Perl ha determinati costrutti che possono essere interpretati solo in fase di esecuzione, il che rende impossibile la compilazione.

D'altra parte l'interpretazione di solito implica che non si debba analizzare tutto il codice sorgente prima dell'avvio del programma. Non riesco a tirar fuori un esempio dalla mia testa, ma non sarei sorpreso se questo significasse che alcune lingue dovessero essere compilate.

Infine non è chiaro come funzioni come la generazione del codice sorgente (ad es. programmazione Lisp meta, macro C, Eclipse EMF) e manipolazione bytecode (ad esempio AspectJ) dovrebbero rientrare in questa immagine.

    
risposta data 10.11.2014 - 07:39
fonte
0

Per un programma in C non c'è motivo per cui il compilatore non possa essere incluso nelle seguenti due righe:

cc -g source.c
./a.out

Che lo rende piuttosto interpretato. Ho aggiunto il -g per sottolineare che è possibile mantenere il codice C vicino all'origine.

E qualsiasi linguaggio interpretato può essere compilato per l'efficienza. Javascript può essere migliorato. Python rilascia quei bei file .pyc.

In breve: la dicotomia che ti è stata insegnata è un'assurdità. I linguaggi di programmazione esistono sull'intero spettro, dal codice nativo al codice della macchina virtuale ai DSL che è possibile scrivere in Java o Scala in catene interpretate di codice compilato che si alimentano l'una con l'altra, che è precisamente la filosofia Unix (e qualsiasi script Bash).

Le lingue descritte come interpretate tendono a non avere errori di tempo "compili". Ma poi ci sono i raccoglitori di pelucchi che possono anche essere integrati nel compilatore e fermarsi se si verifica un errore, molto nello stile del mio codice giocattolo qui sopra.

Forse interpretato significa più "dinamico", il che significa che meno cose causano errori di compilazione o errori di runtime. Ma anche un linguaggio come Java, che le persone chiamano più severe, può caricare classi malformate e generare errori di runtime.

E un linguaggio "compilato" come C viene compilato in assembly / codice macchina. E qual è il codice macchina se non il codice che viene interpretato dalla CPU? Il codice compilato deve atterrare da qualche parte.

Che è solo lo stesso processo che il compilatore Java passa dal codice sorgente Java a quello Java, che è interpretato dalla JVM più o meno nello stesso modo in cui il codice Python è interpolato dal runtime di Python. Quindi abbiamo un linguaggio compilato che compila in un'interpretazione che viene eseguita su una macchina virtuale programmata in una lingua nativa (C ++).

E naturalmente i linguaggi giocattolo come i brainfuck che puoi implementare in Java o C o Ruby, e sono abbastanza semplici da poterli scrivere in assemblaggio proprio come un esercizio di apprendimento. Ma poi di nuovo Ruby può essere messo su JVM tramite JRuby, il che rende Ruby molto più simile a un linguaggio compilato.

Scaricalo ancora?

    
risposta data 10.11.2014 - 06:22
fonte

Leggi altre domande sui tag