[Python] Parere su Go di un professore di informatica (delle superiori) nonche' uno dei fondatori di ERLUG
Davide Muzzarelli
d.muzzarelli a dav-muz.net
Ven 10 Lug 2015 20:21:23 CEST
Il 10/07/2015 16:19, Carlos Catucci ha scritto:
> Attendo risposte (che con il vostro permesso riportero' all'esimio prof,
> nonche' amico di vecchia data)
Uso Go in produzione da un anno e mezzo circa, in poco tempo ho
sviluppato un software per gestire i prodotti di un eCommerce più
qualche altro tool per me (server SMPP, websocket e altre cose più piccole).
Il programma ha diverse funzioni sia come server web che da linea di
comando, lavora su 3 database diversi contemporaneamente (Postgresql,
MSSQL e MySQL) per gestire dati tra Microsoft Navision, Magento e dati
aggiuntivi suoi. Ha interfacce web e CLI, non ho dovuto usare alcun
framework, è estremamente veloce rispetto a Python, consuma un decimo
della memoria che consuma Python e non ha i problemi di GIL.
> * La sintassi è presa "parzialmente" dal C, ma con strane modifiche
> che lo rendono soggetto a errori inconsci. Per esempio la scelta di
> avere il tipo di dato DOPO la variabile. Il che crea costrutti
> particolamente poco chiari come x := float32(y) che non è solo
> un'assegnazione.
La sintassi è presa a piene mani dal C. L'obiettivo era permettere ai
neo-laureati, che solitamente hanno studiato C a scuola, di essere
subito produttivi in pochi giorni.
In pratica è come un C fatto per chi viene da linguaggi di scripting.
> * I controlli (if, then, else, switch) sono abbastanza carini, ma
> anche qui l'idea di poter preporre un'assegnazione prima del
> controllo ne fa perdere un po la leggibilità. Carini anche se non
> immediati i vari range, map, un po' presi da python e ruby.
then non esiste in Go.
if è identico agli altri linguaggi tranne la possibilità opzionale di
creare un'assegnazione con scopo privato, e mi pare molto chiara come
espressione dato che la logica sarebbe prima di creare una variabile e
poi di usarla:
if err := eseguiQualcosa(); err != nil {
...
}
switch/case è simile ad altri linguaggi, molto facile da leggere:
switch valore {
case "vero":
return true
case "falso":
return false
default:
return nil
}
map è un semplice hash:
numeri := map[string]int{
"uno": 1,
"due": 2,
"tre": 3,
}
print(numeri["uno"])
range è completamente diverso da Python.
Python: for x in tupla
Go: for k, v := range tupla
> * La gestione degli array multidimensionali fa rabbrividire, a momenti
> è meglio quella di Javascript che pure è atroce. :-)
In Go puoi solo avere array di array.
> * Interessante la gestione dei canali per lo scambio dei dati tra thread
E' un pattern e lo hanno implementato in maniera molto comoda da usare e
prevenendo i soliti errori comuni, in effetti ha semplificato
notevolmente l'uso di parallelismo e concorrenza.
> * defer è un'innovazione, ma che serve in soldoni?
defer è estremamente utile per scrivere software stabile, serve quando
vuoi essere sicuro che venga eseguita una funzione anche in caso di errore.
Un esempio banale è quando vuoi essere sicuro che venga chiuso un
descrittore di un file o una connessione dopo averlo aperta.
In questo esempio, il file verrebbe chiuso correttamente anche nel caso
in cui f.Write() restituisse un errore:
f, _ := os.Open("nome del file")
defer f.Close()
n, err := f.Write("foobar")
if err != nil {
return "Errore, spazio su disco esaurito"
}
Inoltre aiuta nella lettura del programma perché in questo modo le
operazioni di apertura sono vicine alle funzioni di pulizia e chiusura.
Se le funzioni fossero lontane, tipo le prime all'inizio della funzione
e le altre alla fine, diventerebbe più facile commettere errori o
dimenticarsi qualcosa inoltre si dovrebbe scrivere il codice per pulire
e chiudere anche in caso di errore.
> * NOn abbiamo approfondito la questione degli oggetti, ma sempra
> un'aggiunta alla fine, più object-based che object-oriented.
Go è decisamente object-oriented e non object-based e lo è usando il
pattern dell'aggregazione al posto di quello dell'editarietà.
Go ha array, scalari ecc. che non sono per niente oggetti.
> Nella mia prospettiva da docente e/o curioso, non vedo un grande appeal
> su questo linguaggio che prende un po' dal C classico, python, ruby,
> java, C# e node/javascript ma non ottiene nè codice di facile lettura
> (tutt'altro) nè codice più stringato. Qual è quindi la "mission" del
> linguaggio? Forse è quella della massima portabilità e velocità di
> esecuzione, ma questo non abbiamo potuto provarlo - forse in futuro?"
Go prende direttamente dal C, ben poco da altri linguaggi.
Ancora non è pronto per applicazioni GUI per scarsità di librerie oppure
per applicazioni web nella maniera classica perché la tipizzazione
statica diventa scomoda da usare rispetto a Python/Ruby.
Go è una via di mezzo tra il C e il Python, attrae molti più
programmatori da Python che da C/C++.
La sintassi è semplice con pochi costrutti, molto chiara, il codice
viene pulito e identato direttamente dai tool forniti col compilatore
(avere uno standard di questo genere è una manna dal cielo per i
software scritti da molte persone), la compilazione semplifica
notevolmente i deploy, la tipizzazione statica previene numerosi bug, il
garbage collector e le interfacce generiche aiutano a guadagnare un
sacco di tempo evitando nel contempo stack overflow e compagnia bella,
il ridotto uso di memoria è fondamentale quando si scalano le
applicazioni (ci sono team che hanno ridotto i server di un ordine di
potenza rispetto a Python/Ruby), le performance sono molto vicine a
quelle del C (e continuano a migliorare).
La filosofia di base è molto simile a quella di Python e di Unix:
- Piccoli componenti altamente specializzati
- Esplicito è meglio che implicito
- Piatto è meglio che annidato
- Sparso è meglio che denso
- La leggibilità conta (per questo Go ha un tool per pulire il codice)
- Grande praticità al posto di grandi filosofie
- Gli errori dovrebbero essere sempre espliciti (infatti gli errori sono
passati come valore, se si vuole vanno esplicitamente ignorati al
contrario che con Python)
- Aggregazione
- Namespace
- Semplicità (Python 3 non mi pare abbia ormai perso questa caratteristica)
- Un solo modo di fare le cose
Per rispondere alla domanda sulla mission, ecco un elenco delle cose
dove Go eccelle:
- API (sia client che server)
- Applicazioni ad alta parallelizzazione e concorrenza
- Applicazioni server di elaborazione dati da molti utenti (es.
map-reduce, elaborazione di immagini, parsing di testi, conversione di
dati ecc.)
- Programmi a linea di comando
- Sistemi in genere (vedi Docker, Reborn, Doozer, Juju, Vitess, Dropbox,
CloudFlare e tanti altri) tranne i sistemi operativi e le applicazioni
in real-time (presto sarà possibile fare del soft-real-time)
- Database distribuiti
La community è in forte crescita ed è decisamente facile leggere il
codice scritto da un'altra persona. Python ha una sintassi ancora più
leggibile ma i programmi scritti in Python non sono altrettanto facili
da comprendere come quelli in Go.
In pratica sostituisce bene Python in tutte quelle situazioni dove sono
richieste performance, basso consumo di risorse, stabilità e
manutenzione di medi o grossi sorgenti. Lo scotto da pagare sono i tempi
di sviluppo maggiori di circa il 50%.
Sostituisce bene C in tutte quelle situazioni dove la velocità di
sviluppo è importante quanto le performance e dove il progetto è di
grandezza media o alta.
Go è un linguaggio che ha i suoi difetti ma sono veramente pochi, anche
Python e C hanno i loro difetti eh.
Detto questo continuerò a scrivere siti web in Python e applicazioni web
in Go ;)
Buona serata,
Davide Muzzarelli
Maggiori informazioni sulla lista
Python