Dopo averci pensato un po ', sto cambiando leggermente la mia risposta.
Ogni lingua può essere compilata. Ma il problema è quanto guadagni da questa compilation. La compilazione ha due vantaggi: il guadagno di prestazioni attraverso l'ottimizzazione e la verifica anticipata degli errori attraverso il controllo delle firme dei tipi. Entrambe queste cose dipendono in gran parte dall'indirizzamento indiretto nel codice. L'indirizzamento è semplicemente un pezzo di codice, che puoi dire cosa accadrà solo quando il codice è in esecuzione. In entrambi i casi di ottimizzazione e controllo dei tipi, qualsiasi tipo di indiretto rende inutili qualsiasi tentativo. Il compilatore non può ottimizzare il codice se non sa cosa succederà dopo o quale struttura funzionerà e non può garantire se i tipi sono corretti se non sa quali parametri può accettare la funzione o cosa è contenuto in una variabile.
Ora, i linguaggi che sono solitamente compilati, come C ++, C # e forse Java, questi contengono piccole correzioni. Ad esempio, in C #, le indecisioni possono essere raggiunte solo tramite metodi e delegati virtuali. Tutto il resto è semplice da prevedere senza dover eseguire il codice. Se chiami Math.Sqrt
, il compilatore sa che al 100% chiamerà solo questo metodo. Il vantaggio derivante dalla compilazione di quelle lingue è enorme.
Dall'altro lato, le lingue che vengono interpretate spesso hanno in genere tonnellate di riferimenti indiretti. Questo spesso deriva dal sistema di tipo dinamico. Ad esempio, in Python, l'attributo di lettura della classe può restituire assolutamente qualsiasi cosa in qualsiasi momento. Non si sa mai se l'attributo read sarà int, string o function pointer. Quindi, anche se li compili, il guadagno è piuttosto trascurabile. Il compilatore può forse pre-analizzare il codice e fare alcune ottimizzazioni minori, ma non può fare cose come la funzione di inlining, che di solito ha un impatto molto più grande sulle prestazioni.
Modifica, vecchio post:
Non so cosa tu non capisca esattamente, perché entrambi questi punti sono piuttosto auto-esplicativi.
Con i linguaggi compilati la struttura del codice e dei dati è statica durante la compilazione e non può essere modificata durante il runtime. Questo non deriva dall'uso del compilatore, ma è necessario essere in grado di compilare una lingua. La struttura statica fornisce quindi informazioni sul compilatore necessarie per prevedere come il codice verrà eseguito e ottimizzato. Lingue come C ++, C # o Java rientrano in questa categoria.
Con linguaggi interpretati, la struttura del codice e dei dati può cambiare. Di solito, quando la struttura non è statica, la compilazione diventa quasi impossibile, quindi è necessaria l'interpretazione. Tuttavia, poiché l'interprete non richiede la struttura statica, la lingua può contenere funzionalità e semantica che consente di modificare i dati e il codice in fase di runtime. Le lingue digitate dinamicamente come Python, Ruby o JavaScript rientrano in questa categoria.