Sto indovinando che la più grande motivazione per questo, e il risultato più grande, è un miglioramento dei tempi di compilazione. Il video di anteprima tecnica ha rappresentato un punto importante della loro capacità di compilare grandi quantità di codice in periodi di tempo brevi (il loro esempio era 200.000 righe di codice in 8 secondi su un MacBook - non sono state fornite le specifiche della macchina).
Anche nel video tecnico, menzionano specificamente che uno dei più grandi modi che hanno ottenuto è stato quello di cambiare il modo in cui i moduli sono stati compilati e collegati.
Ecco un esempio di come qualcosa sarebbe lavorare in una corrente C/++ sistema C:
Classe A è definita nel file di intestazione C_H e attuata C_CPP. La classe B deriva da C ed è implementata nei file B_H e B_CPP. La classe A deriva da B ed è implementata nei file A_H e A_CPP.
A causa delle catene di derivazione, A_CPP include A_H, B_H e C_H. B_CPP include B_H e C_H. C_CPP include C_H. A causa della natura del preprocessore C, che trasforma essenzialmente un #include in un'operazione di copia e incolla, il contenuto di C_H viene eseguito attraverso il compilatore 3 volte e B_H viene eseguito due volte.
Inoltre, i contenuti di A_CPP, B_CPP e C_CPP vivono tutti nei propri file oggetto. Quindi quando il linker va a risolvere A.o, è obbligato a caricare ed elaborare sia B.o che C.o. Inoltre, quando risolve B.o, deve elaborare nuovamente C.o.
Le intestazioni precompilate possono aiutare un bel po 'con la prima parte di questo problema, ma possono anche essere un problema reale da mantenere e conosco molti sviluppatori che semplicemente non li usano per questo motivo. Inoltre, non cambia radicalmente il problema: le intestazioni vengono ancora elaborate a più livelli più volte, solo ora viene elaborato un binario precompilato al posto dell'origine. Sono stati tagliati diversi passaggi, ma non l'intero processo.
Go si avvicina alle cose in modo diverso. Nelle parole dritto fuori dalla PDF from their tech talk:
"Il compilatore Go tira transitiva dipendenza tipo di informazioni dal file oggetto - ma solo ciò di cui ha bisogno Se A.go dipende B.go dipende C. .go: - Compila C.go, B.go, quindi A.go. - per compilare A.go, il compilatore legge Bo not Co In scala, questo può essere un enorme aumento di velocità ".
OK, viene eseguita una leggera tangente. Perché è rilevante? La risposta è anche nel Go Tech Talk PDF:
"Modello di pacchetto: dipendenze esplicite per abilitare build più veloci."
Sto indovinando che gli sviluppatori Go hanno preso la posizione che quando i tempi di compilazione sono misurati in secondi, anche per progetti molto grandi, che è più produttivo per gli sviluppatori di mantenere tempi di compilazione quel breve. Supponiamo che mi occorrono 8 secondi per compilare 200.000 righe di codice e scoprire che ho importato un pacchetto estraneo, 5-10 secondi (con un buon IDE o una buona familiarità con l'ambiente di sviluppo) per trovarlo e risolverlo, e altri 8 secondi da ricompilare. Chiamalo per 30 secondi in totale - e ora tutte le mie future compilazioni rimangono nella gamma dei 10 secondi. Oppure possiamo far crescere il nostro modulo includendo dipendenze non necessarie e osservando che il tempo di compilazione sale da 8 a 10, 12 o 15 secondi. Non sembra molto perché siamo tutti abituati a compilare i tempi nell'ordine dei minuti - ma quando inizi a capire che si tratta di un degrado delle prestazioni del 25%, ti fermi a pensarci per un minuto.
I tempi di compilazione sono già velocissimi. Si consideri inoltre che le velocità del processore sono ancora in aumento (se non così tanto come in passato) e che il numero di core disponibili è in aumento (e la compilazione di grandi quantità di codice è adatta al multithreading). 200.000 righe di codice in 8 secondi oggi significano che non è irragionevole immaginare 200.000 righe di codice che compili essenzialmente istantaneamente in 10 anni. Penso che il team di Go abbia preso una decisione consapevole qui per rendere i tempi di compilazione una cosa del passato, e mentre il problema che si presenta è solo una piccola parte di questo, lo è ancora una parte di quello.
Su un'altra nota, il team di Go sembra aver sviluppato una filosofia di progettazione linguistica che costringe alcune buone pratiche di programmazione.A loro merito, hanno fatto lo sforzo per ottenerlo senza gravi penalizzazioni delle prestazioni, e in gran parte riuscite. [A parte: le uniche due cose a cui posso pensare che influiscono negativamente sulle prestazioni sono la garbage collection e le variabili inizializzate forzatamente - e quest'ultima è piuttosto banale in questo giorno ed età.] Questo farà arrossire timidamente alcuni programmatori, mentre rende felici gli altri . È una vecchia, vecchia argomentazione nel mondo della programmazione, ed è abbastanza chiaro da che parte Go è venuto giù, che ti piaccia o no.
Penso che le due forze abbiano influenzato la loro decisione, e penso che alla fine è un buon modo per andare, anche se sostengo altri commentatori qui che hanno suggerito di permettere una bandiera "--strict" o alcuni tale da rendere facoltativo questo particolare comportamento, in particolare durante le prime fasi del ciclo di vita di un progetto. Potrei facilmente vedermi definire variabili o includere pacchetti quando inizierò a scrivere codice che so di aver bisogno in seguito, anche se non ho ancora scritto il codice che ne ha bisogno.
+1 per la progettazione basata su IDE. Ho raggiunto la stessa conclusione, in gran parte dal fatto che solo i file oggetto hanno qualcosa che assomiglia a un'intestazione, e anche che Go include moduli per l'analisi di Go. –