[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