di  -  mercoledì 18 novembre 2009

Da giorni non si parla d’altro nei forum, nei blog e nei siti che in generale sono legati al mondo della programmazione. Considerato il nome della rubrica e la sete di conoscenza che caratterizza tipicamente i coder smanettoni, l’occasione, come si suol dire, è stata ghiotta.

Essendo poche e di carattere molto generale le informazioni che sono circolate, mi sono fiondato sul sito ufficiale ad attingere dalla documentazione fornita a corredo: Language Design, FAQ, Tutorial, Language Specification e infine Effective Go sono state rispettivamente le letture che mi hanno tenuto compagnia le nottate passate.

In attesa di poterci smanettare (purtroppo al momento gli unici s.o. supportati sono Linux e Mac OS X) per carpire qualche altro utile dettaglio che in genere viene fuori con un po’ di pratica, alcune considerazioni si possono comunque già fare…

Non si soffermerò troppo sulla sintassi, che può piacere o meno a seconda dei propri gusti personali (sui quali è sempre bene non discutere), ma c’è da dire che sicuramente molti avranno storto il naso. Gli affezionati di C & derivati, perché se ne discosta abbastanza, e gli altri perché… sembra il solito linguaggio ispirato al C.

A prima vista con le famigerate parentesi graffe per racchiudere i blocchi di codice, i classici operatori del C, il for, lo switch, lo struct, e i tipi di dato (int, float, e perfino i puntatori), sembra di trovarsi di fronte a un degno rappresentante della famiglia.

Passando però in rassegna tutto, si scopre come l’impronta sia fortemente pascaliana. I package richiamano sicuramente alla memoria Java, ma anche le unit del vecchissimo UCSD Pascal e dei ben più noti Turbo Pascal e Delphi di casa Borland. La dichiarazione delle variabili, fatta eccezione per l’assenza dei due punti che separano l’elenco delle variabili dal tipo, è spiccicata quella del Pascal (come pure l’operatore di “dichiarazione con inizializzazione”, di cui parlerò dopo, che usa il simbolo := ).

Per definire nuovi tipi si usa, in maniera similare, la keyword type; idem per le costanti. Il punto è virgola non è obbligatorio per terminare un’istruzione, ma è un separatore e può essere omesso in alcune occasioni. Attorno alle condizioni (nell’if, for, e switch) non sono obbligatorie le parentesi tonde, l’istruzione case può specificare un elenco di valori, e la dichiarazione dei parametri permette di raggrupparli per tipo.

Probabilmente avrò dimenticato qualcos’altro, ma l’obiettivo non era quello di una comparazione puntuale di ogni singolo costrutto sintattico messo a disposizione del linguaggio, i cui autori comunque ammettono senza problemi le loro fonti di ispirazione (C, Pascal, Modula, Oberon e principalmente; questi ultimi due della stessa famiglia del Pascal), anche se personalmente ho trovato qualche traccia di Python (slice, mappe/dizionari, funzione range per gli iteratori, assegnamento multiplo).

Sintatticamente, quindi, è un linguaggio che prova ad accontentare tutti, credo con scarsi risultati. La domanda che ci si pone di fronte a un nuovo linguaggio, però, è un’altra: quali innovazioni porta con sè? Quali nuovi concetti permette di esprimere che in precedenza non fosse possibile con altri?

Francamente non ne ho trovati. I punti di forza di Go sono ovviamente ciò che chiama goroutine, uno strumento più raffinato di ciò che in letteratura viene chiamata coroutine (una subroutine che si può lanciare e sospenderne l’esecuzione in maniera programmatica) da più di quarantanni e che si trova implementata in diversi linguaggi di programmazione in qualche forma (tasklet, generatori, iteratori, pipe, ecc.).

Mi piace comunque il modo in cui sono state implementate, con l’utilizzo di quelli che vengono definiti come channel per spedire e ricevere informazioni (sempre di un solo tipo) fra le varie goroutine, che richiamano alla mente il concetto di pipe (o del classico modello produttore / consumatore).

Trovo la sintassi semplice e concisa, e sarà apprezzata da chi smanetta con la parallelizzazione del codice. Anche se, come dicevo, sono concetti già noti e implementati in altri linguaggi (Stackless ha esattamente lo stesso modello, incluso il nome channel per i “canali” di comunicazione).

Altra caratteristica interessante è rappresentata dalle interfacce. Anche questo è un concetto ben noto, e permette di definire in maniera precisa un insieme di operazioni (metodi, per la precisione) per modellare delle funzionalità. Non è necessario, come in altri linguaggi, che un tipo di dato implementi specificamente un’interfaccia: è sufficiente che fornisca gli stessi metodi con lo stesso nome e signature per essere utilizzabile in qualunque posto dove viene utilizzata una determinata interfaccia.

Questo è sicuramente molto comodo, ma noto in quest’approccio una tendenza dei progettisti di Go a cercare di separare a tutti i costi la definizione dei tipi di dati dal codice che li riguarda, evitando accuratamente di parlare di ereditarietà anche quando a tutti gli effetti ci si trova davanti (un’interfaccia può riferirsi al suo interno ad altre interfacce, dalle quale “prende in prestito” l’elenco dei metodi definiti; in Go viene chiamato “embedding“).

Detto ciò, e per come si presentano, mi sfugge al momento il modo in cui è stata implementata questa caratteristica. E’ possibile che, tramite reflection (supportata da questo linguaggio), si riesca a risalire ai metodi di un certo tipo e, quindi, a referenziali dove l’interfaccia ne fa uso. Altra possibilità è che venga creata dal compilatore una tabella dei metodi se si accorge che un determinato tipo viene utilizzato in un’interfaccia. Entrambe le soluzioni hanno pregi, difetti, e relativi costi, ma il meccanismo è in ogni caso utile e flessibile.

Per quanto riguarda i tipi di dati, Go ne mette a disposizione parecchi di tipo intero, dagli 8 ai 64 bit, con o senza segno, un paio (con e senza segno) che hanno la stessa dimensione della word dell’architettura (quindi a 32 o 64 bit; al momento), e infine uno che ha la stessa dimensione dei puntatori (32 o 64 bit). E’ presente un tipo booleano, un tipo virgola mobile a 32 e 64 bit, e uno che può essere a 32 o 64 bit a seconda dell’architettura.

Ovviamente è possibile definire delle strutture di dati eterogenei (come le struct di C e derivati), ma più interessanti sono le stringhe (immutabili, come in Java, Python, e altri linguaggi), e gli array di cui è possibile definire degli slice (cioè prenderne un sottoinsieme) da passare a funzioni; non ne viene fatta una copia (come in Python, ad esempio), ma l’array viene referenziato internamente.

Estremamente utili sono poi le mappe, che permettono di definire degli hash/array associativi/dizionari tramite una coppia chiave-valore che può essere anche di tipo diverso. Sono presenti i puntatori, con una sintassi simile al C, ma la nota dolente per gli affezionati di questo linguaggio è che ne manca del tutto l’aritmetica. Quindi niente giochetti sommando interi per far avanzare puntatori: è roba “unsafe“, mentre Go si pone come linguaggio robusto che non vuole riproporre l’incubo dei segmentation fault.

E’ anche possibile definire costanti, tipi funzione (da passare usualmente come parametri), le funzioni anonime che tanti programmatori Java sognano per la versione 7 (tranne PGI-Bis, eccentrico utente della sezione Programmazione del forum di hardware upgrade), si possono passare argomenti in quantità e tipo variabile, ed è anche dotato di parecchi operatori.

Tornando ai punti di forza che vengono messi in evidenza dai creatori, fra questi c’è la velocità di compilazione che deriva dal fatto che il linguaggio non è molto complesso (ad esempio mancano le eccezioni, l’overloading di funzione ed operatori, i generic, l’ereditarietà) ma soprattutto dall’utilizzo dei package per modularizzare il codice. Niente file include come il C, quindi, ma è possibile compilare i package e importare velocemente quanto serve.

La modularizzazione del codice non è però, esclusiva di Go, ma è anch’esso un concetto molto vecchio (Modula e successori ne sono un’evidente testimonianza). Idem per i tempi di compilazione: linguaggi come Turbo Pascal prima e Delphi macinano milioni di righe in pochi secondi e implementano tante funzionalità che a Go mancano. Non serviva, quindi, un nuovo linguaggio per ottenere ciò che la storia ci ha consegnato già da un pezzo, anche se linguaggi come il C continuano imperterriti e masochisticamente a farne a meno aggrappandosi al preprocessore.

La compattezza nella definizione e assegnazione di valori alle variabili è un altro pallino che si porta dietro questo linguaggio. Chi lavora con gli oggetti, template / generic, array, ecc. sa quanto estremamente verboso possa risultare il codice che ne fa uso, visto che il tipo di dato dev’essere specificato sia nella dichiarazione della variabile che nella creazione dell’oggetto vero e proprio.

Go risolve il problema con l’operatore := (di pascaliana memoria), che richiede il solo nome della variabile a sinistra (per la sua dichiarazione), e ne recupera il tipo dall’espressione alla sua destra (per la creazione), utilizzando quello che tecnicamente viene chiamato type inference (anch’esso già utilizzato in altri linguaggi). Codice più corto, ma anche più leggibile, ed è sicuramente un pregio.

La velocità d’esecuzione è un altro tema molto caro ai creatori di Go, che sulla carta dovrebbe raggiungere prestazioni simili al C. Al momento manca una nutrita suite di benchmark, ma qualche appassionato si è cimentato e i risultati sono dir poco sorprendenti: proprio nell’uso delle go/coroutine Go mostra prestazioni di molto inferiori a Stackless (un branch di Python che elimina l’uso dello stack e implementa nativamente questo meccanismo), che al contrario di Go non fa uso di codice compilato nativamente, ma si affida a una classica Virtual Machine.

Sarà colpa dell’esempio (preso, comunque da un talk sul linguaggio tenuto dagli autori), o magari del progetto che è ancora relativamente immaturo (tanto che Google non lo utilizza ancora in produzione nei suoi sistemi), ma certamente non è una buona carta di presentazione per chi è interessato principalmente alla velocità. D’altra parte l’uso disinvolto dei tipi da parte di Go lascia pensare che una qualche forma di “dinamicità” sia in esso presente, e ciò ovviamente si paga.

Altra nota dolente è la robustezza del codice, anch’essa propagandata come caratteristica di punta del linguaggio. Go si propone spesso come safe, e per lo più lo è sicuramente, ma lascia aperte delle pericolose porte delegando al programmatore il rischio di alcune scelte. Se ciò può andar bene per il C, che di questa presunta “totale libertà” del programmatore ne fa anzi un vanto, non la ritengo accettabile per un linguaggio che si propone come “sicuro”.

Tre i punti critici rilevati finora. Uno dagli stessi autori, che ammettono senza mezzi termini che l’uso delle mappe non è thread-safe per questioni puramente prestazionali (leggasi: chi ne ha bisogno utilizzi dei lock). Un altro dal precedente link sui benchmark che sottolinea come l’uso delle interfacce non mette al sicuro da utilizzi impropri delle strutture manipolate (e fa l’esempio dell’ordinamento di un vettore, che però potrebbe cambiare proprio durante quest’operazione).

Un altro l’ho scovato leggendo la guida Effective Go, in cui vengono mostrati degli esempi di utilizzo del linguaggio, e riguarda le mappe. A quanto pare l’accesso a una mappa con una chiave non presente in essa causa il crash dell’applicazione. Viene, pertanto, suggerito un metodo alternativo e “sicuro”. Personalmente trovo incredibile che sia presente quello che ritengo un grave e pericoloso bug del linguaggio, per la facilità con cui può capitare.

Chiudo questa rassegna focalizzando l’attenzione su un altro dei punti di forza propagandati per questo linguaggio. Gli autori citano senza mezzi termini la programmazione di sistema e di come possa essere frustrante. Ma Go utilizza estensivamente un garbage collector; la gestione della memoria (dis/allocazione) è, infatti, interamente affidata a questo collaudato (utilizzato anch’esso da tempo in altri linguaggi) strumento.

Conoscendo i vincoli che si porta dietro questo settore, non mi trovo assolutamente d’accordo con quanto alacremente affermato. La programmazione di sistema richiede un fine e preciso controllo della gestione della memoria, che non può certo essere demandato a un garbage collector.

Mancano, tra l’altro, appositi handler che il C++, ad esempio, mette a disposizione proprio per avere un totale controllo di come dis/allocare la memoria in precise parti del codice. Non è, inoltre, prevedibile quando un oggetto sarà distrutto e le relative risorse rilasciate.

Concludendo, che dire di Go? Posto che siamo di fronte a un nuovo prodotto che maturerà in futuro (ricordiamoci che dietro c’è un colosso come Google), per il momento mi lascia un senso di déjà vu, quindi di qualcosa di già visto, vissuto. Per essere chiari, non ritengo sia il linguaggio che sconvolgerà il mondo e prenderà il posto di C/C++ o anche Java/C#.

Penso che, risolti i problemi di velocità delle goroutine che sembrano attanagliarlo, troverà la sua naturale collocazione nella realizzazione di server semplici da scrivere ma che devono sopportare elevati carichi di lavoro. Ma la mente a questo punto si ferma ad Erlang, che… esiste già da parecchio tempo e si presta molto bene allo scopo.

Déjà vu, appunto, ma almeno un’occhiata la consiglio ai programmatori C (non di sistema) che sono frustrati dalla povertà di questo linguaggio che ancora oggi presenta costrutti sintattici e tipi di dato da età della pietra informatica…

25 Commenti »

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.

  • # 1
    zephyr83
     scrive: 

    Ma la “compilazione” come funziona? ed è facile portare il programma su diverse piattaforme?

  • # 2
    Gas
     scrive: 

    Acc.. questo Google Go me l’ero proprio perso !
    Grazie per la dritta: una di queste notti provo a dargli un occhiata !

  • # 3
    Cesare Di Mauro (Autore del post)
     scrive: 

    @zephyr83: la compilazione è in tutto e per tutto simile a un’applicazione C/C++, perché il compilatore Go è basato su GCC (che è stato opportunamente modificato allo scopo).

    Il porting penso sia semplice, perché non ho visto dipendenze da particolari piattaforme, e ci si affida alla libreria standard.

    Tra l’altro, come dicevo nell’articolo, ha dei tipi interessanti che si mappano sulla particolare architettura su cui gira. Mi riferisco in particolare a uintptr, che è un int senza segno della stessa dimensione dei puntatori: utilissimo per mappare interi o puntatori nelle strutture dati, in maniera interscambiabile, a seconda delle necessità.

  • # 4
    javaboy
     scrive: 

    Ottimo articolo.
    A quando un articolo su erlang?

  • # 5
    Cesare Di Mauro (Autore del post)
     scrive: 

    Penso che passerà un po’ di tempo, perché la mia intenzione è di studiarmelo in maniera più approfondita e lavorarci un po’. In particolare per farci interagire Python.

    Questo perché a lavoro in alcune occasioni un mio collega ha sviluppato delle applicazioni in Erlang. Io, invece, ne sviluppo in Python. Per cui se troviamo un modo per “collaborare” ne trarremo sicuramente giovamento (e ci possono scappare un paio di bei articoli: sul linguaggio e sull’interazione fra i due).

  • # 6
    zephyr83
     scrive: 

    Ma questo linguaggio permette già di realizzare applicazioni grafiche? se quindi realizzo qualcosa su linux (visto che per ora si programma solo su questo sistema operativo o su osx) c’è modo di far girare il programma anche su windows ricompilando soltanto? nn sarebbe male e sarebbe sicuramente un punto a favore per questo linguaggio altrimenti, dopo aver letto questo articolo, nn capisco perché mai uno sviluppatore dovrebbe iniziare a interessarsi a questo linguaggio di programmazione visto quanti ce ne sn (almeno allo stato attuale)

  • # 7
    Cesare Di Mauro (Autore del post)
     scrive: 

    Per il momento Windows non è supportato. Non so se la libreria standard supporta qualche interfaccia grafica, ma in mancanza il linguaggio espone delle comode funzionalità per l’importazione di funzioni e dati dall’esterno (quindi realizzati da altri linguaggi, come il C).

  • # 8
    TheFoggy
     scrive: 

    Devo dire che alcune cose mi han fatto tornare in mente i bei tempi delle superiori, quando si programmava in Turbo Pascal! Quanto tempo è passato.. :(
    Fossi stato in BigG, avrei aspettato un pochino a rendere pubblica la notizia..per via di alcuni affinamenti che contrastano con quanto presentato (mi riferisco alla sicurezza-non sicura e alla velocità-non veloce!). Come presentazione, non è stata di certo ottima, ecco..
    La sintassi di inizializzazione “bimodale”, ho paura possa generare confusione (un po’ di variabili inzializzate in un modo e altre in un altro..dal mio punto di vista “sporcano” la stesura del codice (senza considerare che quella più compatta, introduce overhead, dato che deve capire il tipo della variabile (nell’esempio, la variabile a)..
    non so..per ora non mi convince appieno.. (sono programmatore C/C++..sono un adoratore della libertà in fase di programmazione! :)), ma sarò felice di dargli un’occhiata! :)

  • # 9
    Griso
     scrive: 

    Mi è diventata subito odiosa questa sintassi (de gustibus come giustamente tu dici).
    Volevo segnalare anche l’ottima implementazione delle coroutine in LUA.

  • # 10
    Cesare Di Mauro (Autore del post)
     scrive: 

    @TheFoggy: da pythonista sfegatato sono un adoratore della cultura del:

    “There should be one — and preferably only one –obvious way to do it”

    per cui il doppio operatore di assegnazione non va giù neppure a me (come pure altre “duplicazioni”).

    Non credo che introduca overhead, perché la type inference avviene in fase di compilazione.
    Ecco, mi sono ricordato che avrei dovuto aggiungere qualcosa di più su questo punto, ma parlando di così tante cose alla fine m’è passato di mente. -_-

    Purtroppo la type inference è molto limitata, nel senso che serve soltanto a far risparmiare la dichiarazione del tipo alla destra, come dicevo nell’articolo. Ma non è aggressiva, come in altri linguaggi, dove l’intera espressione viene analizza per cercare di dedurre il tipo e, quindi, poterne fare anche del tutto a meno di dichiararlo.

    Diciamo che è una soluzione di compromesso che hanno adottato per non complicare ulteriormente il compilatore e, quindi, renderlo più lento, visto che ciò avrebbe comportato una perdita di tempo.

    Sul discorso della libertà, credo che sia dovuto ai troppi anni passati a programmare principalmente in assembly, e tante volte in C. Forse è una fase di rigetto causata dagli innumerevoli problemi e sbattimenti di testa contro il muro che ho dovuto affrontare per i famigerati bug che si vengono a creare lavorando così a basso livello.

    @Griso: la sintassi non piace neppure a me. Se non si fosse capito dal pezzo, sono di matrice pascaliana e adoro le sintassi più leggibili (in particolare, che abbiano meno simboli, e più parole chiave: meglio una parola in inglese che un geroglifico).

    LUA non lo conosco bene. Conosco la sintassi (se non l’ho già dimenticata, visto tutto il tempo che è passato da quando l’ho studiata), ma non la libreria a corredo di questo linguaggio (che personalmente trovo poco espressivo: è ridotto troppo all’osso, per i miei gusti).

  • # 11
    Roby
     scrive: 

    Da sviluppatore agile Java… preferisco di gran lunga un codice leggibile ad un codice sintetico…
    non riesco davvero a capire il vantaggio di scrivere un codice utilizzando solo 100 caratteri anzichè 120… mi sembra completramente inutile, soprattutto se a scapito della leggibilità.
    Le parti di codice mostrate nell’articolo non sono a mio parere molto leggibili.

  • # 12
    NeXuS
     scrive: 

    Bell’articolo, ma io trovo il test fatto con Stackless Python piuttosto fallace.

    La ragione risiede nel fatto che le Tasklet di S.Python non sono dei thread veri e propri, ma vengono gestite dalla VM (per quello che mi e’ dato di capire dalla pagina Wiki del sito).

    Le goroutines, al contrario, sono thread veri e propri.

    Ho controllato i dati riportati da Dalke Scientific ed ho fatto dei test tutti miei, ed il risultato e’ che il programma Go passa piu’ o meno lo stesso tempo in userspace ed in kernelspace. Viceversa il programma S.Python dal kernel non ci passa proprio (se non per le strettissime necessita’).

    Credo che se si complicasse un po’ la routine (invece di una semplice addizione), le differenze nei tempi di esecuzione si stringerebbero e potrebbero persino ribaltarsi.

    Come altra nota vorrei segnalare che ci sono due compilatori Go. Uno e’ goc ed e’ un progetto tutto nuovo. L’altro e’ gccgo, ed implementa un frontend Go per gcc. Allo stato attuale gccgo genera del codice migliore, ma compilarlo e’ una follia (invece ho compilato goc in circa 15 minuti sul mio portatile).

    Ho appena fatto un post in proposito sul mio blog
    http://nexus.thenexus.it/wordpress/2009/11/19/stackless-python-vs-go/

  • # 13
    Alè
     scrive: 

    Praticamente un tornare indietro di 6-7 anni.
    WOW

  • # 14
    Cesare Di Mauro (Autore del post)
     scrive: 

    @NeXuS. Se ci fai caso, nell’articolo alla voce “tasklet” ho messo il link a wikipedia che parla di “Green Threads” proprio per evidenziare che non si tratta di thread gestiti dal s.o., ma “emulati” dalla virtual machine.

    Detto ciò, come giustamente affermi, le prestazioni dipendono dal carico di lavoro.

    L’esempio che ho citato è stato realizzato sulla base dell’esempio fornito nel talk, e serve a mostrare che non è necessariamente vero che Go, con le sue goroutine, garantisca prestazioni elevate. Infatti proprio con quest’esempio c’è una soluzione basata su Stackless, che è basata su VM, che mostra prestazioni nettamente superiori.

    Visto che hai la possibilità di eseguire dei test, sarebbe interessante se potessi fare una prova utilizzando psyco, che è un compilatore JIT per Python (supporta fino alla 2.6). E’ sufficiente installarlo (“python setup.py install” dalla cartella in cui hai decompresso il suo archivio) e modificare il sorgente aggiungendo soltanto questo due righe:

    import psyco
    psyco.full()

    P.S. Poi è sempre meglio utilizzare la funzione xrange anziché range per questioni prestazionali: quest’ultima è più lenta se usata semplicemente per eseguire cicli, perché ogni volta genera una lista (nel tuo caso di 1000 elementi, interi).

    @Alè: a cosa ti riferisci esattamente?

  • # 15
    NeXuS
     scrive: 

    @Cesare Di Mauro

    Grazie per i consigli: ho provato sia con xrange che con psyco, ma i risultati sono paragonabili (psyco taglia il tempo di esecuzione di un paio di secondi).

    Python e’ uno splendido linguaggio, ma per determinati codepath non esiste che una VM riesca a star dietro a del compilato.

    Per altro il punto di forza di Go, riguardo alla riduzione dei tempi, e’ proprio in compilazione, non tanto in esecuzione (che comunque e’ veloce).

  • # 16
    Cesare Di Mauro (Autore del post)
     scrive: 

    Python non è nato per essere veloce, ma per scrivere velocemente programmi. :)

    Comunque è destinato a migliorare anche dal punto di vista prestazionale. Io ho sviluppato una versione di Python che è mediamente più veloce di quella ufficiale ( http://code.google.com/p/wpython/ ) e c’è la stessa Google che sta lavorando su questo fronte ( http://code.google.com/p/unladen-swallow/wiki/ProjectPlan ).

    Tra l’altro è anche molto veloce nella compilazione del codice, ma la cosa interessante è che può anche ricaricare al volo un modulo senza far ripartire l’applicazione. Per chi sviluppa server è una preziosa funzionalità.

  • # 17
    NeXuS
     scrive: 

    Mai messo in dubbio: Python e’ probabilmente il linguaggio piu’ leggibile che c’e’ in giro.

    Mi fanno solo sorridere determinate affermazioni che non vengono commentate a dovere da chi fa i test (come a voler provare chissa’ cosa): se si usassero Thread invece che Tasklet, penso che i tempi di esecuzione sarebbero simili (per il semplice caso mostrato).

    Se Go supportasse i Green Thread (ma ci vorrebbe una VM, o comunque una libreria piuttosto pesante), le prestazioni sarebbero simili.

    La mia considerazione e’ che: paragonare un tizio che va in motorino in autostrada (ammesso che possa), con uno che va con un CBR-1000 in statale non ha molto senso.

  • # 18
    Cesare Di Mauro (Autore del post)
     scrive: 

    Però dimentichi una cosa importante: da programmatore è importante il risultato finale, non come lo si ottiene.

    E seconda cosa, Go ha una forma di coroutine (goroutine) e Stackless pure (tasklet), e sono state semplicemente messe a confronto.

    Attualmente il primo le implementa facendo uso i thread di sistema e il secondo coi suoi green thread. In futuro potrebbero anche cambiare, chi lo sa, ma rimane un dettaglio dell’attuale implementazione, non del linguaggio di per sé. ;)

  • # 19
    NeXuS
     scrive: 

    Uhm… no, credo che non sia corretto comunque.

    Il concetto di coroutine e’, per l’appunto, un concetto, una astrazione.

    Dire che l’implementazione non conta e’ come dire che compilare del codice senza ottimizzazioni e’ la stessa cosa che compilarlo con: non conta dal punto di vista della validita’ del risultato finale, ma conta molto dal punto di vista del tempo di esecuzione… ed e’ proprio il tempo di esecuzione che veniva messo in discussione nell’articolo.

    Poi, a parte i vari echo, devo ancora trovare un server che sia leggero tanto quanto l’esempio riportato nel Google talk. Continuo a ritenere le affermazioni fatte su Dalke Scientific molto poco scientifiche.

    “Why then does Pike sound so proud about the performance of Go on this timing test? I don’t know.”

    Io lo so e mi appare evidente: era un esempio volutamente minimale teso a mostrare la semplicita’ del linguaggio ed una relativa velocita’ di esecuzione.

    Bisogna comunque ricordandosi che il punto forte di Go rimane la velocita’ di compilazione, non di esecuzione, e, come ho dimostrato, con un carico di lavoro solo vagamente importante, Stackless le prende di brutto.

  • # 20
    Giogio
     scrive: 

    Ho letto la settimana scorsa gli articoli su go sul sito google ma non l’ho ancora provato.
    Mi è sembrato più che altro un tentativo di creare un linguaggio che renda i costi di programmazione più bassi.
    Un programmatore in grado di usare con profitto la libertà del C++ si forma in tempi lunghi, hanno voluto creare un linguaggio con meno flessibilità ma più semplicità per gli obbiettivi della programmazione moderna: multitasking e sicurezza.
    Tutte cose già viste e già presenti ma non tutte assieme.
    Come wave, niente di nuovo a pezzi, ma nuovo nel suo insieme.
    Poi ci vogliono dei compromessi, sacrificare sicurezza per efficenza ha senso, il fine non è il linguaggio ma la crezione di programmi ad un costo inferiore a quello oggi ottenibili con altri linguaggi, a parità di risultati.

    Sarà più veloce programmare in go? Ci sarà meno necessità di tempo speso in debugging e in controlli?
    Vedremo, molto dipenderà anche dall’ambiente di sviluppo e dalle librerie.
    Personalmente mi piacciono la tipizzazione, i package, le interfacce, meno la garbage collection ma ne capisco l’esigenza.

  • # 21
    Cesare Di Mauro (Autore del post)
     scrive: 

    @NeXuS : non ho detto che l’implementazione non conta, ma che è un dettaglio della medesima, non del linguaggio.

    Attualmente la differenza fra le goroutine di Go e le tasklet di Stackless sta nel fatto che il primo distribuisce le sue coroutine (perché sono coroutine a tutti gli effetti, come puoi leggere nei diversi documenti, di cui ho fornito i link in cui se ne parla) su più thread, mentre Stackless no (sfrutta quello principale).

    Nulla a toglie che quest’ultimo in futuro possa fare lo stesso, visto che le enormi similitudini (e se vedi anche gli esempi a confronto fra Go e Stackless, è lampante di come sia l’approccio sia la stesura stessa del codice abbiano più di qualche somiglianza).

    Per quanto riguarda i risultati in termini puramente prestazionali, è chiaro che dipendono dall’implementazione. Non potrebbe essere altrimenti, perché i linguaggi non si possono confrontare soltanto sulla carta. E il confronto rimane lecito, com’è stato fatto.

    Se non li ritieni scientifico, io la penso in maniera diversa, perché è stato Pike a vantarsi per primo di creare 100mila “microthread” e macinare dati, con Go a processare il tutto in scioltezza (rispetto ad altri linguaggi, s’intende).

    Gli autori del benchmark l’hanno preso in parola ed effettuato dei test, col suo stesso esempio e con un linguaggio che forniva un concetto molto simile, sebbene girasse su una VM. Fornendo sorgenti e dettagli sui test, in modo che siano riproducibili anche da altri. Come poi tu stesso hai fatto e hai appurato. ;)

    Sulla velocità di compilazione mi sono già espresso nell’articolo. :P

    @Giogio: linguaggi che siano semplici, multitasking e sicuri esistono già da tempo. ;)

    Sul resto concordo.

  • # 22
    Tambu
     scrive: 

    non ci ho capito una mazza, ma ti stimo un casino lo stesso! :)

  • # 23
    Nicola
     scrive: 

    ottimo articolo, molto esaustivo.

    Sulla questione leggibilità del codice vorrei aggiungere solo una cosa: molte volte non dipende solamente dal linguaggio di programmazione usato, ma da chi scrive il codice….

  • # 24
    diggita.it
     scrive: 

    C’è posto per Google Go? Prime impressioni sul nuovo linguaggio di BigG…

    Da giorni non si parla d’altro nei forum, nei blog e nei siti che in generale sono legati al mondo della programmazione. Considerato il nome della rubrica e la sete di conoscenza che caratterizza tipicamente i coder smanettoni, l’occasione, come si…

  • # 25
    Antonio
     scrive: 

    Salve a tutti…CERCO PROGRAMMATORI (meglio se esperti in PHP o Erlang, ma nn è obbligatorio esserlo) con voglia di lavorare, conoscenza dell’inglese, e disponibilitá a spostarsi all’estero…se qualcuno é interessato contattatemi a : antonio 83 franco {AT} gmail {punto} com

    ciao!

Scrivi un commento!

Aggiungi il commento, oppure trackback dal tuo sito.

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.