Usare o non usare un Framework?

Stasera ho avuto una interessante conversazione con un amico sull’opportunità o meno di utilizzare un framework di sviluppo (o una o più librerie, come ad esempio JQuery e Bootstrap di Twitter) per la realizzazione di applicazioni.
Da questa semplice premessa è iniziato uno “scontro tra titani”: da una parte il mio amico, che difende la modalità di sviluppo completamente “da zero”, realizzando da zero tutte le funzionalità necessarie per lo sviluppo dell’applicazione (comprese le funzionalità ancillari, come un DatePicker JavaScript ed un framework di validazione dell’input utente JavaScript, ad esempio), dall’altra c’ero io che ovviamente difendevo la modalità di sviluppo che prevede l’utilizzo di framework o librerie di terze parti.
Chi difende la modalità di sviluppo “da zero” porta a sostegno della propria tesi alcune motivazioni come:
  • Estrema personalizzazione: il software fa esattamente quello per cui è stato progettato, massimizzando le performances;
  • Leggerezza: essendo il codice sviluppato estremamente minimale ed estremamente personalizzato, non c’è nemmeno “un byte” di troppo rispetto a quanto necessario;
  • Controllo: si è assolutamente certi di cosa il codice sorgente faccia, senza doverlo controllare e verificare;
  • Conoscenza: risolvendo in proprio ogni problema, si aumenta la propria “conoscenza di base”, entrando nel merito ed analizzando ogni singolo piccolo problema che si può presentare;

Dall’altra parte, ovviamente, chi difende la modalità di sviluppo basata su software di terze parti, porta altre motivazioni:

  • Rapidità di sviluppo: utilizzando framework o librerie già pronte, si accorciano notevolmente i tempi di sviluppo (cosa che rende intrinsecamente più competitivi, potendo offrire al cliente dei tempi di sviluppo minori e conseguentemente minori costi di sviluppo);
  • Riusabilità: un proprio snippet di codice sviluppato utilizzando un framework standard può essere facilmente riutilizzato in un altro progetto, senza alcun o con pochissime modifiche;
  • Evitare di perdere tempo “reinventando la ruota”: non si perde tempo a risolvere per ogni progetto una problematica già affrontata e risolta da tempo, magari da decine di sviluppatori, arrivando ad una soluzione largamente accettata e condivisa, che ormai può essere data quasi per “scontata”;
  • Aderenza agli standard: l’uso di framework e librerie ampiamente diffusi rende facilmente condivisibile e manutenibile anche da persone terze il proprio codice sorgente, per la standardizzazione della sintassi e la necessaria adozione delle best practices che con il tempo di sono venute a creare;
  • Accrescimento personale: imparando a sviluppare con framework diffusi comporta implicitamente un accrescimento personale ed una “maggiore rivendibilità” dello sviluppatore sul mercato del lavoro;
  • Concentrarsi sul reale obiettivo del progetto: non dovendo investire parte del proprio tempo a risolvere problemi ancillari, si può massimizzare i propri sforzi sull’analisi delle problematiche per la quale l’applicazione è in fase di sviluppo, magari investendo parte del tempo nella ricerca di qualche algoritmo particolarmente efficiente o innovativo per la problematica in oggetto;

E voi, cosa ne pensate?
Sviluppate tutto “da zero”, oppure preferite appoggiarvi a framework e librerie già pronti? Fatemi la vostra opinione.

Codemunity: un nuovo social network per sviluppatori

Rieccomi qui: sono passati parecchi mesi dal mio ultimo post in questo blog, ma purtroppo la vita spesso ti travolge senza che tu te ne accorga… e ti ritrovi in meno di un attimo a dover trascurare molte attività personali per far fronte ad impegni impellenti. D’ora in poi conto di riuscire a postare con la regolarità alla quale vi avevo abituato…
Ma veniamo all’oggetto di questo post: da pochi giorni è nata Codemunity, un nuovo social network per sviluppatori, creato dall’amico Matteo Capucci (lo trovate su Twitter a @mattecapu, oltre all’account ufficiale della comunità @codemunity).
In Codecomunity i programmatori potranno scambiarsi tra di loro impressioni, idee, snippet di codice con persone che coltivano la nostra stessa passione, il tutto in un ambiente dall’interfaccia semplice, lineare ed essenziale, del tutto congeniale a noi sviluppatori. 🙂

Insomma, se siete programmatori (per passione, per lavoro o per entrambi i motivi), dovete dare a Codecomunity una possiblità iscrivendovi e partecipando alla nostra piccola comunità in crescita.
Vi aspettiamo 🙂

SQL: calcolare i totali progressivi

Molto spesso, durante le analisi dati richieste dai clienti, viene richiesta l’elaborazione dei totali parziali, per riuscire ad avere facilmente una idea dell’andamento progressivo dei dati.
Purtroppo nella definizione SQL standard non esiste un operatore per questo tipo di calcolo: alcuni database, come SQL Server di Microsoft, offrono una implementazione proprietaria (attualmente lo statement COMPUTE, nelle prossime versioni sostituito da ROLLUP, una sorta di “GROUP-BY”) ma se la nostra esigenza è quella di mantenere una compatibilità cross database, oppure se stiamo lavorando con un database che non supporta questo tipo di operatori, come possiamo risolvere il problema?
Supponiamo di avere una tabella Orders, così definita:
CREATE TABLE [dbo].[Orders](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [OrderID] [int] NOT NULL,
    [OrderDate] [date] NOT NULL,
    [Amount] [money] NOT NULL
)
Come possiamo estrarre i dati, calcolando il totale complessivo?
Utilizzando questa SELECT:
select O.OrderID,O.OrderDate,O.Amount,
    (select SUM(Amount) from Orders where ID<=O.ID) AS RunningAmount
from Orders O
“It’s a kind of magic!!!” O forse no? 🙂
Il campo “RunningAmount” è definito come una subquery all’interno delle query principale, che effettua la somma di tutti i valori contenuti nel campo Amount aventi come ID un indice inferiore o uguale all’ID della riga corrente.
Semplice, rapido e funzionale… e sopratutto, valido per tutti i database, senza doversi appoggiare a “fastidiose” estensioni proprietarie.

Notazione ungara: un bene o un male?

Visto il successo ed i numerosi attestati di soddisfazione circa l’ultimo post di “programmazione teorica” (Linguaggi di sviluppo: tipizzazione forte o debole?) ho pensato di dare seguito ad una serie di post che affrontino alcuni aspetti della programmazione forse meno conosciuti o poco discussi, ma con i quali ogni programmatore si trova giocoforza prima o poi a doversi confrontare.
L’argomento di discussione di oggi è la notazione ungara (o notazione ungherese) della varibili, ossia quella convensione usata in programmazione, secondo la quale nel nome della varibile è necessario indicare il suo tipo.
La notazione è stata ovviamente pensata per essere indipendente dal linguaggio ed è stata molto utilizzata nei vecchi linguaggi come il VB6 i quali, non supportando la tipizzazione forte (vedi post precedente per i dettagli sull’argomento) anche se non è mai stata ratificata alcuna specifica ufficiale circa i prefissi da utilizzare, generando quindi un po’ di anarchia.
Alcuni esempi:
  • lngCount: numero long
  • strTemp: stringa
  • hwndWindows: handle di una finestra
  • bFlag: variabile boolean
Come si diceva poco sopra, la notazione ungara è stata a lungo diffusa tra i programmatori dei linguaggi senza tipizzazione forte, perchè di ausilio durante le fasi di scrittura del codice perchè si aveva immediatamente sott’occhio, nel nome della variabile stessa, il suo tipo, aiutando quindi a prevenire triviali errori di cast.
Il mondo informatico è comunque sempre stato spaccato circa l’utilità della notazione ungara ed anche parecchie personalità importanti (come Linus Torvald) si sono schierate contro:
Inserire il tipo della funzione nel suo nome (la cosiddetta notazione ungara) è una scemenza: il compilatore conosce comunque il tipo e lo può verificare, e l’unica cosa che fa è confondere il programmatore. Non stupisce che la Microsoft [che usa questa notazione] faccia programmi difettosi.
Personalmente ho sempre trovato la notazione ungara troppo “pesante”, il codice diventa di difficile lettura oltre che di difficile manutenzione: si ipotizzi ad esempio di avere un contatore che dal tipo Int deve passare ad un tipo Long, per questioni di dimensioni: non sarà sufficiente, volendo continuare a seguire la notazione ungara, semplicemente cambiare il tipo della variabile ma sarà anche necessario rinominarla, operazione che, anche con l’ausilio di un editor avanzato che supporti il renaming automatico delle varibili, richiederà comunque un certo tempo mentre invece, se non si dispone di un editor di questo tipo, sarà necessario operare manualmente, con tutti i rischi ed i possibili errori di regressione che una operazione del genere potrebbe introdurre.
Voi cosa ne pensate? Pro o contro notazione ungara?

Linguaggi di sviluppo: tipizzazione forte o debole?

Da una piacevole discussione nata su Twitter con il buon Matteo Capucci @mattecapu (a proposito, per chi se lo fosse perso, mi trova su twitter all’account @albertoarmida) è nato lo spunto per questo post, che più che un post informativo (come solito) vuole essere un post di riflessione per gli “addetti ai lavori” (ossia per i programmatori).
Attualmente siamo letteramente circondati da linguaggi di programmazione di livello più o meno alto, di impostazione prettamente top-down (programmazione sequenziale) o i più moderni linguaggi ad oggetti.
Qualsiasi linguaggio di programmazione che si rispetti consente all’utente di dichiarare variabili dove memorizzare i dati elaborati dai propri algoritmi, ed è proprio da questo concetto di variabile che è nata la discussione: meglio un linguaggio di programmazione debolmente tipizzato o un linguaggio fortemente tipizzato?
Prima di procedere oltre, chiariamo il concetto di tipizzazione: con tipizzazione si intende l’associazione tra una variabile ed un tipo di dato.
Molti linguaggi di programmazione consentono di avere quella che può essere definitiva come “tipizzazione debole” o “tipizzazione dinamica“, ossia una variabile è in grado di cambiare il proprio tipo durante l’esecuzione del programma.
In pseudocodice:

var x;        // (1)
x := 5;       // (2)
x := “ciao”;    // (3)

In buona sostanza quindi, alla riga 2 la variabile è di tipo intero, mentre alla riga 3 assume il tipo stringa.
Con la cosiddetta “tipizzazione forte” o “tipizzazione statica” invece una variabile in fase di chiarazione viene appunto abbinata in modo statico e definitivo ad un tipo e non può essere mai cambiato durante l’esecuzione del flusso di codice.
Sempre facendo un esempio in pseudocodice:

int x;        // (1)
x = 5;       // (2)
x = “ciao”;    // (3) → rifiutata dal compilatore

A primo acchito potrebbe venire da pensare che solo i linguaggi più antichi ed ormai superati consentano la tipizzazione debole, mentre invece i linguaggi più moderni consentono solamente la tipizzazione forte, ma non è così: PHP, ad esempio è un linguaggio debolmente tipizzato mentre invece C è fortemente tipizzato.
Non si tratta quindi di una questione legata alla vetustà o meno del linguaggio di programmazione scelto, quanto piuttosto di una vera e proprio scelta fisolofica.
I sostenitori della tipizzazione debole sostengono che le varibili debolmente tipizzate consentano una maggior flessiblità di programmazione, evitando di dover magari dichiarare un elevato numero di variabili di appoggio (per calcoli temporanei, ad esempio) per ciascun tipo.
Viceversa i sostenitori della tipizzazione forte usano questa flessibilità proprio come “arma” contro la tipizzazione debole, asserendo che il mancato controllo a priori dei tipi in fase di compilazione presta facilmente in fianco all’introduzione di bug dovuti proprio a problemi di conversione: si pensi ad esempio all’assegnazione di una variabile stringa rappresentante una data ad una variabile di tipo data piuttosto che, per un bug logico, l’utilizzo di una variabile debolmente tipizzata contenente la stringa “ciao” presupponendo che però questa contega valori numerici… il crash è assicurato.
Personalmente sono assolutamente a favore dei linguaggi fortemente tipizzati anzi, forse con una visione un po’ “talebana”, arrivo addirittura ad impostare i compilatori in modo tale da rifiutare i cast impliciti come ad esempio l’assegnazione di una variabile intero ad una variabile in virgola mobile: è fattibile, non andrà mai in crash (dato che dal punto di vista matematico, gli interi sono un sottoinsieme dei numeri in virgola mobile), ma personalmente, se questo avviene, dato che i tipi dato sono dimensionalmente diversi, a mio avviso c’è un errore nella logica dell’algoritmo.
Voi cosa ne pensate? Meglio un linguaggio “flessibile” ma forse più prono ad errori o un linguaggio più “rigido”, ma che impone quindi al programmatore un piccolo effort ulteriore in fase di programmazione, evitando però fastidiosi crash a runtime?