Perché i compilatori self-hosting considerano un rito di passaggio per le nuove lingue?

27

In diversi punti ho sentito dire che le persone si aspettano che le lingue utilizzino, o almeno lo siano, un compilatore self-hosting per meritare rispetto.

Sono curioso di sapere perché è così. Un compilatore sembra un software molto significativo da scrivere, e immagino che non tutte le lingue siano adatte a crearle. Non avrebbe più senso passare lo sforzo lavorando in qualcosa che darà risultati migliori?

    
posta Chris Cooper 24.11.2014 - 17:14
fonte

9 risposte

27

Wouldn't it make more sense to spend the effort working in something that will give better results?

Come cosa?

La cosa bella dei compilatori è che non hanno molte dipendenze. Ciò li rende buoni candidati per una nuova lingua che probabilmente non ha ancora una libreria standard molto ampia o diversa.

Ancora meglio, richiedono una varietà di cose, pur essendo anche ben studiate. La varietà aiuta a fare in modo che il tuo esempio collauda varie parti della lingua. Essere ben studiati significa avere altri compilatori con cui confrontarsi, oltre a dare più credibilità agli accademici che sai cosa stai facendo.

E mentre i compilatori sembrano un sacco di lavoro, sono piuttosto piccoli nel grande schema delle cose. Se gli esecutori linguistici non possono nemmeno fare qualcosa che hanno già fatto nella nuova lingua, come faranno cose nuove? Come gestiranno le cose veramente grandi come le librerie standard o un IDE?

    
risposta data 24.11.2014 - 17:28
fonte
28

L'obiettivo di avere un compilatore nella lingua che viene compilata è spesso parte della pratica di " mangiare il tuo cibo per cani ". Dimostra al mondo che consideri il linguaggio, il compilatore e l'ecosistema di moduli e strumenti di supporto per essere "abbastanza buono per un lavoro serio" o "pronto per la produzione".

Ha anche l'effetto virtuoso di forzare coloro che sono più vicini al linguaggio, al compilatore e al design runtime per affrontare direttamente gli effetti di tutte le decisioni che hanno preso e le priorità di sviluppo che hanno scelto: verruche e tutto il resto. Questo porta spesso a un gruppo centrale che in teoria non solo comprende l'ambiente linguistico, ma ha una vasta esperienza pratica che usa il linguaggio / gli strumenti nel crogiolo di condizioni difficili, in termini reali.

    
risposta data 24.11.2014 - 17:36
fonte
16

Le persone creano nuove lingue di uso generale per una ragione principale: odiano almeno una cosa su ogni altra lingua là fuori. Questo è il motivo per cui così tante lingue non vengono decollate. Hai una grande idea per una lingua che possa migliorare la tua vita di programmazione, ma devi fare la prima implementazione in una lingua che ti infastidisce almeno in un modo. Self-hosting significa che non devi più lavorare in quella vecchia lingua fastidiosa. Ecco perché i creatori di una lingua lavorano per quel passaggio e lo considerano un importante traguardo.

Molte funzionalità linguistiche sembrano buone sulla carta, ma quando si arriva a utilizzarle in un progetto reale si iniziano a vedere i loro limiti. Ad esempio, un sacco di lingue non hanno inizialmente un supporto unicode decente. Completare un progetto di grandi dimensioni aiuta a garantire che molte di queste situazioni siano state incontrate e affrontate, e un compilatore auto-hosting è un buon progetto come qualsiasi altro. Ecco perché le persone diverse dai creatori della lingua lo considerano un importante traguardo.

Ciò non significa che sia la pietra miliare di solo degna di nota. C'è una funzionalità che non è esercitata da un compilatore, come l'integrazione del database, le interfacce grafiche, il networking, ecc.

    
risposta data 24.11.2014 - 18:22
fonte
10

Steve Yegge ha scritto un ottimo post sul blog che, indirettamente, indirizza gli indirizzi questo.

I

Big point n. 1: comprendono praticamente tutti gli aspetti dell'informatica. Sono un corso di livello superiore perché è necessario conoscere tutte le altre cose che si apprendono nel curriculum di informatica per iniziare. Strutture dati, ricerca e ordinamento, prestazioni asintotiche, colorazione grafica? È tutto lì dentro.

C'è una ragione per cui Knuth ha lavorato alla sua monumentale (e inarrestabile) "Art of Computer Programming" per diversi decenni, anche se è iniziato come (solo) un libro di testo per il compilatore. Allo stesso modo in cui Carl Sagan ha dichiarato: "Se desideri creare una torta di mele da zero, devi prima inventare l'universo", se vuoi scrivere un compilatore, devi prima occuparti di quasi ogni aspetto dell'informatica.

Ciò significa che se il compilatore è auto-ospitato, allora è abbastanza sicuro di essere in grado di fare ciò di cui ho bisogno, qualunque cosa stia facendo. Al contrario, se non scrivi un compilatore nella tua lingua, c'è una buona probabilità che manchi qualcosa che è veramente importante per qualcuno, perché gli implementatori linguistici non hanno mai dovuto scrivere un programma che avrebbe richiesto loro di pensare su tutti questi problemi.

Punto grosso n. 2: da 30.000 piedi, un numero sorprendente di problemi assomigliano proprio ai compilatori.

Compilers take a stream of symbols, figure out their structure according to some domain-specific predefined rules, and transform them into another symbol stream. Sounds pretty general, doesn't it? Well, yeah.

Che tu sia nel team di Visual C ++ o meno, molto spesso ti troverai a dover fare qualcosa che assomigli a una parte di un compilatore. Lo faccio letteralmente ogni giorno.

A differenza della maggior parte delle altre professioni, i programmatori non usano solo strumenti, ma costruiscono i propri strumenti. Un programmatore che non può (per mancanza di competenze, o la mancanza di strumenti utilizzabili con cui costruire altri strumenti) scrivere strumenti sarà per sempre handicappato, limitato agli strumenti che qualcun altro fornisce.

Se un linguaggio non è "adatto alla creazione di" programmi che possono prendere un flusso di simboli, applicare loro delle regole e trasformarlo in un altro flusso di simboli, che suona come un linguaggio piuttosto limitato, e non uno che sarebbe utile per me.

(Fortunatamente, non penso che ci siano molti linguaggi di programmazione che non sono adatti alla trasformazione dei simboli. C è probabilmente tra i peggiori linguaggi utilizzati al giorno d'oggi, tuttavia i compilatori C di solito sono auto-ospitati, quindi non si fermano mai chiunque.)

Una terza ragione finirò con, per esperienza personale, non menzionata da Yegge (perché non stava scrivendo su "why self-host"): scuote i bug. Quando scrivi un compilatore, significa che ogni volta che lo lo compila (non solo ogni volta che esegui ), ne fai affidamento perché funzioni e funzioni correttamente contro un codebase di dimensioni decenti (lo stesso compilatore).

Questo mese ho usato un compilatore non-self-host relativamente nuovo e famoso (probabilmente puoi indovinare quale), e non posso andare 2 giorni senza segmentare la cosa. Mi chiedo quanto i designer abbiano effettivamente dovuto usarlo.

    
risposta data 11.06.2016 - 21:28
fonte
7

Se vuoi che un compilatore per il linguaggio X sia self-hosting, devi prima implementarlo in qualche altra lingua, ad esempio Y, in modo che richieda l'input per il linguaggio X e sputa il codice assembly, o un codice intermedio , o anche codice oggetto per la macchina su cui è in esecuzione il compilatore. Vuoi scegliere la lingua Y per essere il più simile possibile alla lingua X, poiché a un certo punto tradurrai il codice scritto in Y in X.

Ma non si vuole scrivere più del compilatore nella lingua Y del necessario, quindi per iniziare, si implementa solo un sottoinsieme del linguaggio - eliminando i costrutti ridondanti. Nel caso di una lingua di tipo "C", while ma non per o do while . se ma nessun caso o terziario op. Nessuna struttura o unione o enumerazione. Ecc. Quello che hai lasciato è solo abbastanza del linguaggio per scrivere un parser e un generatore di codice rudimentale per il linguaggio X. Quindi controlla l'output. Anche in questo caso.

Una volta che hai funzionato, puoi riscrivere l'origine del compilatore che è stata scritta nella lingua Y nella lingua X e compilare il sorgente X della lingua usando il compilatore scritto nella lingua Y. L'output sarà un nuovo compilatore scritto nella nuova linguaggio X che compila il linguaggio X, cioè ora è self-hosting. Tuttavia non è completo poiché hai implementato solo un sottoinsieme della lingua nella lingua Y.

Quindi ora aggiungete le funzionalità mancanti, testando ciascuna (o gruppo di funzionalità) che generano codice corretto. Ad esempio, una volta implementata la funzione nel compilatore, è possibile scrivere programmi di test usando le nuove funzionalità, compilarli e testarli, ma non si dovrebbero ancora utilizzarli nella sorgente del compilatore. Una volta verificate le nuove funzionalità, è possibile utilizzare queste nuove funzionalità nella sorgente del compilatore stesso, magari sostituendo parte del codice originale scritto nel sottoinsieme della lingua, ricompilando l'origine del compilatore utilizzando la versione con le nuove funzionalità.

Ora hai un meccanismo per aggiungere nuove funzionalità al linguaggio - e, una volta che la generazione del codice per le funzionalità è stata verificata correttamente, possono essere utilizzate nella generazione successiva del compilatore stesso.

Indietro 60 anni fa quando i computer sono arrivati per la prima volta sulla scena (e più tardi quando sono arrivati per la prima volta i microprocessori), non c'erano altri linguaggi adatti per l'implementazione del compilatore iniziale. Quindi i primi compilatori dovevano essere scritti in codice assembly e quindi, quando era in esecuzione una quantità sufficiente del compilatore, il codice assembly veniva sostituito dalla versione scritta in una nuova lingua. Neanche un assemblatore? L'intero processore è sceso di un altro livello, con l'assemblatore inizialmente scritto nel codice macchina .

    
risposta data 26.11.2014 - 01:34
fonte
2

È possibile produrre un linguaggio di programmazione che non è ben progettato per scrivere un compilatore ma è ben progettato per qualche altro scopo?

Guardando un linguaggio come SQL suppongo che la risposta sia sì. Ma le lingue di quella natura non sono di uso generale.

    
risposta data 25.11.2014 - 11:27
fonte
2

Chi lo dice? ... comunque, è solo un'opinione. Alcuni potrebbero essere d'accordo, altri no, non c'è giusto o sbagliato qui. Alcune lingue hanno compilatori scritti in sé, altri no. Qualunque sia.

Tuttavia, penso che sia un buon esercizio / proof-of-concept se un linguaggio è in grado di "auto-compilare" ... è solo ... bello ... e dimostra che il linguaggio è adatto per fare qualcosa roba complessa.

Vorrei anche dire che nonostante sia bello, ci sono ancora una serie di motivi per cui un compilatore potrebbe essere scritto in un'altra lingua. Ad esempio, la maggior parte dei motori javascript non sono scritti in javascript. Ci sono molte ragioni per questo: integrazione con altri software, collegamento a librerie / dipendenze esistenti, strumenti superiori, prestazioni, codice legacy ... A volte, il linguaggio auto-compilante è bello, ma ha ancora senso mantenere il compilatore principale in un altro. Tuttavia, la lingua ha senso per sé. Di solito non puoi permetterti di riqualificare un intero ecosistema.

    
risposta data 24.11.2014 - 17:23
fonte
2

Clang è scritto in C ++. Non sarebbe troppo difficile riscrivere il compilatore Clang Objective-C in Objective-C, ma sarebbe abbastanza inutile. Qualsiasi modifica nel compilatore C ++ dovrebbe essere ripristinata in Objective-C e viceversa. Allora perché?

Ora c'è un compilatore Clang Swift. Sicuramente il compilatore potrebbe essere riscritto in Swift. Ma quale scopo sarebbe? Per dimostrare che il linguaggio è abbastanza potente per scrivere un compilatore in esso? A nessuno importa se puoi scrivere compilatori in Swift. Le persone fanno si preoccupano se riesci a scrivere le interfacce utente in Swift e puoi farlo in modo dimostrabile.

Se hai un compilatore ben testato che può essere facilmente adattato per compilare linguaggi diversi, è piuttosto inutile riscriverlo in lingue diverse, a meno che la riscrittura in una lingua diversa renda più semplice lavorare con il compilatore. E se avesse senso scrivere Clang in Swift, ad esempio, i compilatori Clang C, C ++ e Objective-C dovrebbero tutti essere scritti in Swift.

Ci sono cose più importanti da fare che provare che puoi scrivere un compilatore in qualche linguaggio di programmazione.

    
risposta data 08.11.2015 - 15:06
fonte
1

Mostra che la lingua è in grado di elaborare elaborazioni di stringhe complesse e di tradurre in un'altra lingua / interpretare se stessa.

Nel processo di creazione di un compilatore (il primo grande progetto) ci sarà un problema che verrà in primo piano.

    
risposta data 24.11.2014 - 17:32
fonte

Leggi altre domande sui tag