Cinque caratteristiche progettuali del linguaggio Go nella prospettiva dell'ingegneria dei sistemi e del backend

Introduzione
I linguaggi di programmazione sono strumenti per costruire prodotti. Il semplice utilizzo di un determinato linguaggio non definisce il livello di competenza di uno sviluppatore. Tuttavia, la scelta di un linguaggio e il modo in cui lo si utilizza possono influenzare direttamente il modo di pensare degli sviluppatori e la loro direzione di crescita. In particolare, uscire dal linguaggio che si utilizza attualmente per confrontarlo con altri linguaggi contribuisce in modo significativo ad ampliare la visione tecnica e a sviluppare una sensibilità per l'essenza delle cose. In questo articolo intendo spiegare, suddividendo il discorso in cinque aspetti, perché ho scelto Go e in che modo esso favorisca la crescita dello sviluppatore.
1. Go è un linguaggio che bilancia prestazioni e produttività.
Esistono innumerevoli linguaggi di programmazione, e ciascuno possiede punti di forza e di debolezza in base alle proprie caratteristiche.
- C offre prestazioni eccellenti e consente il controllo a basso livello, ma richiede allo sviluppatore di gestire direttamente la memoria e, mancando di funzionalità di alto livello, presenta una produttività ridotta e una manutenzione difficoltosa.
- C++ e Rust supportano diverse funzionalità avanzate, come la programmazione orientata agli oggetti, i template e la metaprogrammazione, ma la sintassi è complessa, la curva di apprendimento è ripida e i tempi di compilazione lenti li rendono poco adatti a distribuzioni ripetute.
- Java e C# garantiscono indipendenza dalla piattaforma e stabilità, e per questo sono ampiamente utilizzati nei servizi su larga scala, ma vengono eseguiti su una macchina virtuale pesante, il che rende complessi la distribuzione e l'ambiente di esecuzione e comporta un elevato consumo di risorse.
- Python e JavaScript sono adatti allo sviluppo rapido grazie alla sintassi concisa e a un ricco ecosistema, ma le prestazioni di esecuzione sono inferiori e l'affidabilità dell'ecosistema è limitata, per cui emergono limiti strutturali nei sistemi di grandi dimensioni.
Al contrario, Golang è un linguaggio che raggiunge un eccellente equilibrio tra prestazioni e produttività. Go, essendo un linguaggio compilato come C, garantisce un'elevata velocità di esecuzione e, grazie ai tempi di compilazione rapidi, offre una flessibilità di distribuzione paragonabile a quella degli interpreti. In altre parole, Go è un linguaggio equilibrato, utilizzabile in modo stabile nella maggior parte degli ambienti senza evidenti svantaggi.
2. Go previene la cargo cult programming.
Durante la Seconda guerra mondiale, le forze alleate costruirono basi aeree su isole del Pacifico per sostenere il conflitto. Il grande afflusso di rifornimenti e di attrezzature militari cambiò profondamente la vita dei militari e degli abitanti locali. Gli isolani videro per la prima volta abiti confezionati, cibi in scatola e altri beni che arrivavano a bordo degli aerei. Al termine della guerra, la base fu abbandonata e i carichi smisero di arrivare. Così gli abitanti dell'isola, per imitare i militari, si vestirono da controllori del traffico aereo, soldati e marinai, costruirono delle piste di fortuna e utilizzarono dei bastoni per inviare segnali di atterraggio agli aerei. Continuarono a marciare nella speranza che i carichi scendessero con i paracadute. Tuttavia, l'aereo che stavano aspettando non arrivò mai.
La cargo cult programming indica l'abitudine di sviluppo che consiste nell'imitare la forma esteriore di codice o di tecnologie senza comprenderne il principio di funzionamento. Tra gli sviluppatori contemporanei, in particolare nel settore dello sviluppo web, si riscontra spesso l'abitudine di seguire ciecamente soluzioni senza conoscerne il significato. Framework come React, Next, Spring e Django hanno reso possibile lo sviluppo senza conoscere la struttura interna, ma spesso non si riesce a reagire adeguatamente anche a un piccolo errore. A ciò si aggiungono gli strumenti di generazione del codice basati sull'intelligenza artificiale, che stanno rendendo sempre più diffuso un metodo di sviluppo in cui, anziché scrivere il codice direttamente o comprenderne i principi, ci si limita a copiare e incollare i risultati.
Go contrasta questo problema alla radice, a livello della filosofia del linguaggio. Go è un linguaggio progettato attorno alla libreria standard anziché attorno ai framework. Lo sviluppatore può costruire un server web di livello produttivo utilizzando soltanto librerie di base come net/http e database/sql, e in questo modo sviluppa naturalmente intuizione e comprensione delle strutture di basso livello, quali la rete, il database e l'I/O. Una struttura che consente di acquisire solide basi senza dipendere dai framework costituisce il fondamento su cui lo sviluppatore può crescere continuamente senza perdere di vista l'essenza della tecnologia.
3. Go offre un potente modello di concorrenza.
Le moderne CPU si stanno evolvendo nella direzione di migliorare le prestazioni sfruttando più core in parallelo, piuttosto che aumentare la velocità del singolo core. Di conseguenza, la concorrenza, che permette a un programma di gestire più attività contemporaneamente, è diventata indispensabile, e cresce l'importanza di un linguaggio che consenta di progettarla e implementarla in modo efficiente. Go è un linguaggio ottimizzato per questo contesto. Una goroutine è un thread leggero fornito da Go, che può essere creato con uno stack di pochi KB e che, anche in presenza di migliaia di esecuzioni simultanee, consuma quasi nessuna risorsa di sistema. Il runtime di Go distribuisce in modo efficiente numerose goroutine sui thread del sistema operativo tramite un proprio scheduler M:N, e questo processo viene ottimizzato automaticamente senza che lo sviluppatore debba intervenire. In questo modo lo sviluppatore può progettare logiche concorrenti in modo sicuro e coerente, senza ricorrere a complesse logiche di sincronizzazione o a schedulazioni personalizzate.
Inoltre, Go supporta attivamente una progettazione moderna della concorrenza, basata su strumenti di sincronizzazione come mutex e waitGroup, nonché su channel e context. Grazie a questa struttura, lo sviluppatore può acquisire in modo naturale un senso pratico di concorrenza e parallelismo senza restare vincolato a teorie complesse, e può raggiungere un livello elevato di astrazione e capacità progettuale applicabile in concreto.
4. Go è un linguaggio creato da eccellenti sviluppatori che ne hanno mantenuto la direzione.
Go è un linguaggio nato per iniziativa di Google e di figure leggendarie come Robert Griesemer, Rob Pike e Ken Thompson. In particolare, questi autori sono i creatori di Unix e del linguaggio C, nonché maestri nel campo dei compilatori e del software di sistema, e ciò dimostra di per sé l'affidabilità tecnica di Go. A ciò si aggiunge l'esperienza pratica di numerosi ingegneri di Google e il know-how maturato nella gestione di servizi su larga scala, per cui Go, fin dall'inizio, mira alla risoluzione di problemi concreti e si è sviluppato mantenendo una filosofia e una direzione coerenti.
Altri linguaggi spesso generano confusione nelle comunità e negli utenti a causa di rotture di compatibilità, modifiche di progettazione, licenze instabili e ecosistemi non standardizzati. Ad esempio, Python ha visto il proprio ecosistema dividersi per anni a causa della rottura di compatibilità tra la versione 2 e la versione 3; Java, dopo l'acquisizione da parte di Oracle, ha visto la propria politica di licenza diventare instabile, e sempre più aziende hanno esitato ad adottarlo. Inoltre, Node.js continua a non offrire un sistema di moduli coerente, poiché CJS ed ESM coesistono tuttora.
Al contrario, Go è un linguaggio che considera la coerenza e la stabilità come valori prioritari. Il team di Go mantiene rigorosamente la retrocompatibilità e, nell'introdurre nuove funzionalità, adotta un approccio di integrazione graduale che non entri in conflitto con il codice esistente. Anche la sintassi evita parole chiave superflue e limita l'astrazione eccessiva, impedendo che il linguaggio diventi inutilmente complesso. Inoltre, toolchain ufficiali coerenti come go fmt, go mod, go build e go test incoraggiano tutti i progetti Go ad avere lo stesso ambiente di sviluppo e la stessa struttura, mentre una libreria standard solida e pratica supporta fedelmente, senza bisogno di framework aggiuntivi, la maggior parte delle funzionalità necessarie allo sviluppo reale, come server web, gestione dei file e integrazione con database.
5. Il Gopher è carino.


