Perché il linguaggio Go?
Introduzione
I linguaggi di programmazione sono strumenti per la creazione di prodotti. La competenza di uno sviluppatore non è semplicemente definita dal linguaggio che utilizza. Tuttavia, la scelta di un linguaggio e il modo in cui viene gestito possono influenzare direttamente la mentalità e la direzione di crescita dello sviluppatore. In particolare, confrontare il linguaggio attualmente in uso con altri può essere di grande aiuto per ampliare l'orizzonte tecnico e coltivare un senso per l'essenza. In questo articolo, intendo illustrare perché ho scelto Go e come esso supporti la crescita dello sviluppatore, suddividendo l'analisi in cinque aspetti.
1. Go è un linguaggio che bilancia performance e produttività.
Esistono innumerevoli linguaggi di programmazione nel mondo, e ognuno presenta vantaggi e svantaggi a seconda delle sue caratteristiche.
- Il C offre prestazioni eccellenti e controllo di basso livello, ma la gestione della memoria deve essere eseguita direttamente dallo sviluppatore, e la mancanza di funzionalità di alto livello comporta una bassa produttività e una difficile manutenzione.
- C++ e Rust supportano diverse funzionalità avanzate come l'orientamento agli oggetti, i template e la metaprogrammazione, ma la loro sintassi è complessa, la curva di apprendimento è ripida e la lentezza della compilazione li rende inadatti per il "deployment" iterativo.
- Java e C# sono ampiamente utilizzati per servizi su larga scala grazie alla loro indipendenza dalla piattaforma e alla stabilità, ma vengono eseguiti su macchine virtuali pesanti, il che rende l'ambiente di "deployment" e di esecuzione complesso e aumenta il fabbisogno di risorse.
- Python e Javascript sono adatti per lo sviluppo rapido grazie alla loro sintassi concisa e al ricco ecosistema, ma le loro prestazioni di esecuzione sono inferiori e l'affidabilità dell'ecosistema è bassa, rivelando limiti strutturali nei sistemi su larga scala.
Al contrario, Golang è un linguaggio che presenta un equilibrio eccezionale tra performance e produttività. Essendo un linguaggio compilato come il C, Go garantisce elevate prestazioni di esecuzione, offrendo al contempo una flessibilità di "deployment" a livello di interprete grazie alla sua rapida velocità di compilazione. In sintesi, Go è un linguaggio equilibrato che può essere utilizzato in modo stabile nella maggior parte degli ambienti senza evidenti svantaggi.
2. Go previene la programmazione "Cargo Cult".
Durante la Seconda Guerra Mondiale, le forze alleate costruirono basi aeree sulle isole del Pacifico per sostenere lo sforzo bellico. Il grande afflusso di rifornimenti e attrezzature militari cambiò notevolmente la vita dei soldati e degli indigeni. Gli abitanti videro per la prima volta aerei che trasportavano vestiti fabbricati, cibo in scatola e altri beni. Finita la guerra, le basi furono abbandonate e i carichi non arrivarono più. Così, gli isolani si vestirono come controllori del traffico aereo, soldati o marinai per imitare i militari, costruirono qualcosa di simile a una pista di atterraggio e usarono bastoni per segnalare l'atterraggio agli aerei. Continuarono a marciare per far sì che il carico venisse paracadutato dagli aerei. Tuttavia, gli aerei che aspettavano non arrivarono.
La programmazione "Cargo Cult" si riferisce all'abitudine di sviluppo di imitare solo l'aspetto esteriore di codice o tecnologia senza comprenderne i principi. Tra gli sviluppatori moderni, in particolare nel settore dello sviluppo web, è comune questa abitudine di seguire senza comprenderne il significato. Framework come React, Next, Spring, e Django hanno reso possibile lo sviluppo senza conoscere la struttura interna, ma spesso si riscontrano difficoltà nel gestire anche un piccolo errore. Inoltre, con l'aggiunta recente degli strumenti di generazione di codice AI, la pratica di copiare e incollare i risultati anziché scrivere codice direttamente o comprenderne i principi è diventata ancora più diffusa.
Go, a livello di filosofia del linguaggio, evita intrinsecamente tali problemi. Go è un linguaggio progettato attorno alla libreria standard, non incentrato sul "framework". Gli sviluppatori possono costruire un web server di livello di servizio reale utilizzando solo librerie di base come net/http e database/sql, e questo porta naturalmente a sviluppare intuizione e comprensione delle strutture di basso livello come la rete, i database e l'I/O. Questa struttura, che permette di padroneggiare le basi in modo solido senza dipendere da un "framework", fornisce una base affinché lo sviluppatore possa crescere continuamente senza perdere l'essenza della tecnologia.
3. Go offre un potente modello di concorrenza.
Le CPU moderne si stanno evolvendo verso il miglioramento delle prestazioni attraverso l'utilizzo parallelo di più core, piuttosto che aumentando la velocità di un singolo core. Di conseguenza, la concorrenza, ovvero la capacità di un programma di gestire più operazioni contemporaneamente, è diventata essenziale, e l'importanza di un linguaggio in grado di progettarla e implementarla in modo efficiente sta crescendo. Go è un linguaggio ottimizzato per questo ambiente. La "goroutine" è un "thread" leggero fornito da Go, che può essere creato con uno "stack" di pochi KB e consuma pochissime risorse di sistema anche quando ne vengono eseguite migliaia contemporaneamente. Il "runtime" di Go distribuisce in modo efficiente le numerose "goroutine" sui "thread" del sistema operativo attraverso il proprio "scheduler" M:N, e questo processo viene ottimizzato automaticamente senza l'intervento diretto dello sviluppatore. Ciò consente allo sviluppatore di progettare la logica di concorrenza in modo sicuro e coerente, senza la necessità di complesse logiche di sincronizzazione o di "scheduling" personalizzato.
Inoltre, Go supporta attivamente la progettazione moderna della concorrenza utilizzando strumenti di sincronizzazione come "mutex" e "waitGroup", nonché "channel" e "context". Grazie a questa struttura, lo sviluppatore può acquisire naturalmente una sensibilità pratica per la concorrenza e il parallelismo senza essere vincolato a teorie complesse, e può raggiungere un alto livello di astrazione e capacità di progettazione utilizzabile partendo da zero.
4. Go è un linguaggio creato e guidato da grandi sviluppatori.
Go è un linguaggio nato sotto la guida di Google e di sviluppatori leggendari come Robert Griesemer, Rob Pike e Ken Thompson. In particolare, essi sono i fondatori di Unix e del linguaggio C, e giganti nel campo dei compilatori e del software di sistema, il che di per sé attesta l'affidabilità tecnica di Go. Con l'aggiunta dell'esperienza pratica e del "know-how" operativo di servizi su larga scala di numerosi ingegneri di Google, Go ha fin dall'inizio mirato alla risoluzione di problemi reali, sviluppandosi con una filosofia e una direzione coerenti.
Altri linguaggi spesso causano confusione nelle comunità e tra gli utenti a causa di rotture di compatibilità, modifiche di progettazione, licenze instabili o ecosistemi non standardizzati. Ad esempio, Python ha visto il suo ecosistema diviso per anni a causa della rottura di compatibilità tra le versioni 2 e 3, e Java, dopo l'acquisizione da parte di Oracle, ha visto un aumento dei casi in cui le aziende esitano ad adottarlo a causa dell'instabilità della politica di licenza. Inoltre, Node.js continua a non offrire un sistema di moduli coerente a causa della coesistenza di CJS e ESM.
Al contrario, Go è un linguaggio che pone la coerenza e la stabilità come valori prioritari. Il team Go mantiene rigorosamente la compatibilità con le versioni precedenti e, nell'introduzione di nuove funzionalità, aderisce a un metodo di integrazione graduale per evitare conflitti con il codice esistente. La sintassi evita anche parole chiave non necessarie e limita l'eccessiva astrazione, impedendo al linguaggio stesso di diventare inutilmente complesso. Inoltre, la "toolchain" ufficiale coerente come go fmt, go mod, go build, e go test induce tutti i progetti Go ad avere lo stesso ambiente di sviluppo e la stessa struttura, e la potente e pratica libreria standard supporta fedelmente la maggior parte delle funzionalità necessarie per lo sviluppo pratico, come web server, gestione dei file e interfacciamento con database, anche senza un "framework" separato.