Nelle precedenti due puntate di questo articolo, ho descritto le prime tre versioni della webapp che "gira" dietro le quinte di questo sito.
Site V1 era basato su Bootstrap, jQuery, Java, Spring Framework e CouchDB.
La versione successiva, V2, era stata arricchita di nuove caratteristiche, ma sopprattutto presentava radicali modifiche lato server. Il motore web era stato completamente ridisegnato in modalità asincrona tramite Vert.X. Spring venne messo da parte.
Con V2, iniziai un nuovo percorso, cercando un "miglior" approccio per costruire la parte server del sito.
La versione V3, nelle mie intenzioni, doveva essere minimale con un approccio più classico, basato su librerie Java di base, ma questa versione non arrivò mai in produzione.
Nuove idee si stavano facendo strada nella mia mente.
Stavo ancora rimunginando su alcuni aspetti della programmazione concorrente che si erano fatti più evidenti durante lo sviluppo di V2: il costo del cambio contesto di un thread e le modalità di accesso a risorse condivise in situazioni di concorrenza.
Notai, su diversi articoli e prodotti nel web, come il concetto di "dati immutabili" stava diventando sempre più importante per costruire applicazioni scalabili e concorrenti.
Dati immutabili significa che non si cambiano direttamente i valori dei dati, ma che si produce una copia modificata dei dati. Questa tecnica è inerente alla programmazione funzionale, rendendo inutile una sincronizzazione per accedere ai dati.
In quel mentre, stavo lavorando anche su alcune app mobili. Avrei voluto usare stessi o analoghi strumenti sia lato client che lato server, sia che avessi dovuto sviluppare un'app web a singola pagina, un'app mobile o un servizio server.
Dati immutabili, programmazione funzionale, sviluppo multipiattaforma... tutto questo mi portò a Clojure. Clojure è un linguaggio funzionale, un dialetto del Lisp. È compilato, pur restando completamente dinamico. Gira sulla JVM e può interagire con Java. Permette uno sviluppo di tipo iterativo grazie alla console REPL.
Clojure fu per me una sfida, dato che ero abituato prevalentemente a linguaggi orientati agli oggetti con tipizzazione statica, ma, comunque, era molto interessante da studiare ed esplorare.
Scelsi come fondazione di V4 il micro-framework Luminus.
Nel frattempo, sperimentavo anche lo sviluppo di applicazioni mobile con ClojureScript + React Native.
Ricostruii la parte pubblica del sito, pagine, articoli e utilità, in Clojure e Luminus. Fu sia una sfida che un piacere. Imparai Clojure grazie all'ottimo "Clojure for the Brave and True". Un libro fantastico!!!
V4 era pronto. Per distribuire l'applicazione, lasciai perdere il mio sistema di distribuzione basata su CouchDB e optai per Git e Fabric, come descritto nel mio articolo "Automatizzare la distribuzione di una web app Luminus con Fabric/fabfile e Git". Semplificai anche l'architettura del mio sito, consolidando il tutto in un solo data center.
Fui soddisfatto del risultato, ma c'era ancora qualcosa su cui investigare e da migliorare.
Trovavo difficile continuare a mantenere e sviluppare questo progetto secondo il paradigma funzionale. Il codice, come sospettavo, era difficile da leggere dopo qualche tempo che lo avevo scritto. La causa forse era la mia poca esperienza in campo funzionale o la mia stessa impostazione mentale. Sentivo la mancanza dell'auto completamento del codice nell'editor e di altri aiuti offerti dai linguaggi a tipizzazione statica.
Anche i miei esperimenti di sviluppo mobile con Clojure non filavano a dovere. Troppi livelli di astrazione rendevano difficile eseguire il debug del software. ClojureScript + React Native richiedevano un computer particolarmente potente per sviluoppare un'applicazione, pena attese snervanti. L'avvio di una sessione di sviluppo comportava un intenso uso di CPU.
Così, dovetti riprendere la mia ricerca per un diverso strumento che venisse incontro alle mie necessità di sviluppo software.
Sviluppo web, sviluppo mobile, sviluppo server, condivisione di strumenti e codice, supporto per le migliori pratiche di programmazione concorrente, IDE e strumentazione... Senz'altro uno sforzo inutile, la ricerca di uno strumento che andasse bene per tutto. Ma, mentre cercavo uno strumento per lo sviluppo mobile, fui colpito da Flutter...
Flutter è un altro framework mobile che promette uno sviluppo efficace sia su Android che iOS. È realizzato da Google. Google, oggigiorno è anche troppo onnipresente nel mondo con il suo motore di ricerca e Android. Avrei preferito usare uno strumento di qualche altra azienda o associazione. Ma, trovavo Flutter troppo interessante, perchè rendeva veramente possibile sviluppare app per i due pricipali sistemi mobile con velocità d'esecuzione nativa e possibiltà di interagire con funzionalità native.
Il linguaggio è Dart. Nulla di veramente nuovo sotto il sole, ma ci sono tutte le caratteristiche che ho potuto apprezzare in tanti diversi linguaggi: tipizzazione statica, moduli, classi, "syntactic sugar" per accedere alle variabili membro, operatori per gestire il valore "null", programmazione asincrona non bloccante facilitata dalla parola chiave "async", veri "generics", multithreading tramite "isolate", etc, etc... e rullo di tamburi fantastica documentazione!!!
Un altro fattore veramente importante è l'attenzione data agli strumenti a contorno: dart analyser è un modulo che espone web API locali utili ad editor ed IDE per fornire completamento automatico del codice, analisi del codice, suggerimenti vari.
E cosa dire di "DartPad", insostituibile per gli estimatori delle console REPL!!!
L'ecosistema del linguaggio Dart comprende, tra varie alternative, AngularDart, per lo sviluppo web e Aqueduct di Stable|kernel, un software ben fatto per sviluppare servizi server.
Decisi quindi di "riscrivere" per la quinta volta il progetto "site" usando Dart e Aqueduct.
Per sviluppare V1, V2 e V3, avevo usato Springsource Tool Suite, un IDE open source basato su Eclipse. Per V4, avevo utilizzato l'editor Atom. Ora, anche se c'erano varie alternative open source, volli usare un IDE commerciale, Webstorm di Jetbrains. Volevo provarlo, confrontandolo con le mie precedenti esperienze con altri editor/IDE, sperando potesse rendermi immediatamente produttivo su un linguaggio nuovo e recente. Non volevo passare per la fase di ricerca e prova dei vari plugin necessari per integrare Dart con qualche IDE o editor. È una mia scelta personale di questo momento.
Aqueduct è un framework HTTP estensibile per realizzare API REST, ma riuscii con relativa facilità ad usarlo per servire pagine web dinamiche grazie agli spunti trovati su GitHub, nelle pagine del progetto Aqueduct, o su StackOverflow o anche nel codice sorgente, quando necessario.
Decisi di lasciar perdere CouchDB e tornare al caro e buon vecchio DB relazionale SQL PostgreSQL. Aqueduct fornisce un semplice, ma buon ORM per accedere a PostgreSQL, con gestione degli aggiornamenti dello schema del DB, ovvero le cosiddette "migrations".
Arrivando da quattro predecedenti "ristrutturazioni" del progetto "site", presto, con relativa facilità, completai site V5 e lo feci girare in produzione. Se stai leggendo questo articolo dal sito giandisa.it, controlla a fine pagina. Se leggi versione 5.x.x, allora questo articolo è prodotto grazie a Dart e Aqueduct, le fondazioni di V5.
Lo so, è un'impresa ardua, se non impossibile, trovare un linguaggio di programmazione o degli schemi o degli strumenti che possano soddisfare tutte le necessità di sviluppo software. Il giusto strumento, linguaggio dipende da molti fattori, tecnici ma non solo...
Però, amo seguire le evoluzioni, i corsi e ricorsi, cercare di scoprire qualche nuova pietra liscia e lucente sulle sponde del fiume dell'informatica, ammirala e adoperarla, sperando possa fornire qualche buon aiuto nel creare qualche nuovo artefatto software.
Durante questi viaggi, ho imparato qualche lezione che, spero, mi abbia reso un miglior sviluppatore ed ingegnere software.
Grazie per aver seguito la storia di questa mia piccola ricerca. Spero sia stata piacevole e che possa esser stata interessante.
Ciao
Gianni Di Sanzo