When was the last time you did something for the first time?
No Translations
Il concetto è semplice: se si impiega più tempo del previsto nel realizzare una funzionalità (perché lo sviluppatore ha incontrato problemi, ha scoperto che non si può fare, ci sono dei bachi nel codice di terze parti usato, ecc.), il requisito associato alla funzionalità può cambiare o addirittura saltare. E’ la legge del time-to-market.
Il cambiamento (annullamento) del requisito provoca una modifica nell’analisi, che si ripercuote a livello di design.
I cambiamenti di design si ripercuotono sul codice scritto, spesso pesantemente. Le conseguenti modifiche fatte al codice possono rallentare o inibire la possibilità di sviluppare le rimanenti funzionalità, o modificare funzionalità preesistenti, con la conseguenza che altri requisiti dovranno essere modificati.
La valanga partita da una pallina di neve travolge tutto ciò che incontra, portandosi via chilometri di codice, tempi stimati, autostima degli sviluppatori, dignità dei Project Manager e salubrità mentale di un po’ tutti gli interessati. Anche le famiglie degli interessati ne avvertiranno le conseguenze, in maniera più o meno lieve.
Lo stress accumulato da uno sviluppatore sul lavoro (il PM gli fa la ramanzina perché non lavora bene e nei tempi previsti) ed in famiglia (la moglie ed i figli lo rimproverano perché fa sempre tardi sul lavoro e torna sempre stanco e non può dedicare loro il giusto tempo), superata una certa soglia, indurrà ad essere meno precisi nell’implementazione delle funzionalità, e quindi ad aumentare i tempi di sviluppo. Qui il proverbiale cerchio si chiude.
by Paolo Rainone
No Translations
Italian Agile Day 2007!
Venerdi 23 Novembre 2007 si terrà a Bologna il quarto Italian Agile Day.
Si tratta di una conferenza gratuita di un giorno dedicata alle metodologie Agili per lo sviluppo e la gestione dei progetti software rivolta agli sviluppatori, project leaders, IT managers, tester, architetti e coach che hanno esperienze da condividere o che iniziano solo ora ad interessarsi a queste tematiche.
La giornata ha come obiettivo la conoscenza pratica, le esperienze sul campo e un attivo coinvolgimento di tutti i partecipanti.
Dopo il successo della scorsa edizione anche quest’anno il formato sarà OpenSpace ma grazie alla presenza di 2 sale vi affiancheremo anche il formato classico!
L’accesso è libero previa registrazione, i posti sono limitati. L’evento, per la seconda volta consecutiva, si auto-finanzierà.
by Paolo Rainone
No Translations
I Giorni Del Ciclo
La maggior parte delle energie di un architetto spesso sono spese nel mostrare agli sviluppatori come implementare la sua architettura, più che a disegnare l’architettura in sè.
Questo comporta alcuni problemi di fondo, perchè un’architettura prova la sua qualità solo dopo esser stata messa in piedi.
E’ possibile valutare l’efficacia di una scelta di design solo dopo che lo sviluppatore ha terminato il suo lavoro, potenzialmente dopo diverso tempo dall’idea progettuale iniziale. A questo dobbiamo aggiungere il tempo necessario per scovare e schiacciare gli inevitabili bug, derivanti da implementazione errata, scritta senza consapevolezza del “tutto”, magari non testata e certamente mal documentata.
Cicli di sviluppo lunghi rendono meno efficace l’architettura, perchè ci vuole molto tempo per “fidarsi” del lavoro fatto.
Cicli di sviluppo corti consentono di aggiustare il tiro con maggiore controllo e velocità, evitando gli sprechi di tempo e di lavoro.
Lontano dalla Vista, Lontano dal Cuore
Consentire alle persone coinvolte di poter “vedere il software” così come sta “venendo fuori”, con proiezioni grafiche concise e chiare, la cui interpretazione è univoca (condivisa tra i membri del team) ed il cui livello di dettaglio può essere variato, come lo zoom di office, in maniera di far focalizzare architetto e sviluppatore sull’aspetto che più interessa in quel momento, (analisi, relazioni fra entità implementative, il flow-chart di un singolo metodo incriminato).
Non parlo di UML ovviamente, in queste cose UML generalmente fallisce miseramente, parlo di linguaggi di modellazione definiti dagli architetti, espressi con i termini che usano gli architetti nel parlare con l’utente, fonemi e grafemi che giorno dopo giorno si consolidano in un Dizionario Condiviso (Ubiquitous Language), a metà strada tra Business e IT.
È l’Architettura Latente (frutto dell’emergent design?), quella effettivamente implementata dal codice degli sviluppatori (che non è mai esattamente uguale a quella degli architetti) a farla da padrone nel cosa si rivelerà un baco, cosa funzionerà, quale modifica si potrà fare, quanto costerà farla e quanto tempo ci vorrà.
Tagliando Software: Equilibratura e Convergenza delle Architetture
Il tentativo e lo sforzo di far coincidere le due architetture (quella vera e quella sognata dagli architetti) ha potenzialmente il triplice effetto di ridurre i bachi derivanti da scarsa comprensione, aumentare l’efficacia del lavoro di architettura e rendere i tempi di sviluppo un po’ più sotto controllo.
Per far coincidere le due architetture, le scelte di design devono essere realizzate nel minor tempo possibile. Al limite della riduzione dei tempi di implementazione, magari pochi secondi o qualche minuto, si materializza nelle mani del designer uno strumento potentissimo, forse il meglio che si può desiderare: la possibilità di provare una soluzione, vedere velocemente se funziona, se è tutto ok si procede oltre altrimenti si aggiusta il tiro: il design-and-fix.
Probabilmente il modo migliore per ottenere questo scopo è demandare la generazione di codice a partire da modelli architetturali direttamente alla macchina, l’esecutore più fedele e privo d’errori che abbiamo a disposizione.
Fin quando ci sarà l’uomo a scrivere codice, ci saranno bachi derivanti da errore umano di codifica.
Ci pensate a quanto sarebbe bello il mondo se non esistessero bachi?
by Paolo Rainone
No Translations
L’Architetto Fa Le Cose Per Bene
Ci si chiede spesso se sia più importante una buona architettura o una buona implementazione a fare la differenza in un prodotto software. L’esperienza mi ha insegnato che, ahimè, è più facile che sia considerato utile un prodotto con un’architettura mediocre ma sostenuto da una buona implementazione. Certamente anche la migliore architettura non serve assolutamente a nulla se l’implementazione è fatta male.
Lo Sviluppatore Fa Le Cose Per Bene
Scrivere codice è un’attività molto complessa, e spesso la complessità di questa attività non è ben dominata dagli sviluppatori, che generalmente si affidano più al ciclo “code-and-fix” (andare per tentativi, con l’aiuto di Tyche) che a tecniche/metodologie di codifica di comprovato successo.
Questo perchè l’attenzione per il “fare meglio” è merce rara, ed anche le persone che hanno sul proprio scaffale libri come “Code Complete” o “Refactoring Patterns” poi alla fine applicano solo quelle idee che condividono o che hanno già sperimentato, mentre “filtrano” le cose che ritengono inutili.
E fin qui nulla di strano, del resto chi farebbe una cosa che ritiene stupida o inutile? Purtroppo così facendo la creazione di un corpus universalis di “rudiments”, cose basilari da sapere e da fare, è ben lungi dall’essere definito, universalmente accettato ed applicato in maniera omogenea. (Mi sovviene al proposito l’imminente libro di Kent Back sugli “Implementation Patterns“).
La difficoltà intrinseca nello sviluppo e la necessità di adottare tecniche implementative il cui dominio è spesso fuori dalla portata degli sviluppatori, sono le cause prime di defects (bacherozzi).
Il Project Manager Fa le Cose Per Bene
Il PM ha sempre ragione, quindi questo paragrafo è mooolto, ma moooolto agile.
Domande Retoriche: Chi Fa Le Cose Per Bene?
Ci pensate a quanto sarebbe bello il mondo se non esistessero bachi?
Quanto sarebbe produttivo un team se tutto il codice scritto funzionasse alla prima compilazione?
Di quanto uscirebbero fuori budget i progetti se non esistesse la regressione?
Ha senso richiedere ad un gruppo di persone di spendere 30 ore nel week-end (in aggiunta alle oltre 40/50 fatte nella settimana passata) per fare un deployment in produzione, per poi scoprire che il software appena rilasciato contiene ancora dei bachi, ha delle parti che sicuremante saranno completamente riscritte nei due/tre mesi successivi, oppure ha delle parti che sicuramente saranno disabilitate perchè producono risultati errati?
Quanto sarebbero più felici quelle persone coinvolte se fosse messo in produzione solo codice funzionante e se il deployment fosse completamente automatizzato, magari con procedure realizzate e testate fin dal primo giorno di sviluppo, dalla prima riga di codice, quando è facile farlo, in maniera che dopo 2/3 anni di lavoro nulla sia più una sorpresa? Scusate l’ovvietà, ma loro sarebbero molto felici.
by Paolo Rainone
No Translations
by Paolo Rainone
No Translations
by CyberViper
No Translations
�
by Paolo Rainone
Other Languages:
L’ineffabile CyberViper mi ha segnalato un ennesima testimonianza della magnificenza di Excel, ovvero un sito dedicato a videogiochi realizzati con il metaspreadsheet (?!) di mamma Microsoft.
Ispirato dalla versatilità di Excel, Maurone non s’è lasciato sfuggire l’occasione di realizzare il suo Language Workbench.
�
by Paolo Rainone
Other Languages:
La lettura di quest’articolo di Dave Inman mi ha inspirato una nuova strip dell’orso Maurone dove introduco AI, un’improbabile intelligenza artificiale alle prese con la comprensione del linguaggio naturale umano.
by Paolo Rainone
No Translations
Venerdì 1 Dicembre 2006 si terrà a Milano L’Agile Day.
Quoto dal sito:
L’Italian Agile Day è una conferenza gratuita di un giorno dedicata alle metodologie Agili per lo sviluppo e la gestione dei progetti software come eXtreme Programming, SCRUM, Feature Driven Development, DSDM, Crystal e Lean Software Development aderenti all’Agile Manifesto.
La conferenza si rivolge agli sviluppatori software, project leaders, IT managers, tester, architetti e coach che hanno esperienze da condividere o che iniziano solo ora ad interessarsi a queste tematiche. Sarà una grande opportunità per scambiarsi idee e condividere esperienze. Il focus della giornata è la conoscenza pratica, le esperienze sul campo e un attivo coinvolgimento di tutti i partecipanti. L’evento è organizzato dall’Italian Agile Movement che festeggia 4 anni di attività.
Per maggiori informazioni:
by Paolo Rainone
No Translations
Alcune tipololgie di test sono la formalizzazione di tutti i requisiti, funzionali e non, descritti al massimo livello di formalismo possibile, ovvero tramite un linguaggio decidibile riconosciuto dall’esecutore target, il nostro beneamato computer. Si possono, e si dovrebbero, fare test per qualsiasi aspetto di un architettura software ed in effetti come ricorda Binder, per considerare un programma “thoroughly tested” sarebbe necessario uno sforzo difficilmente sostenibile.
Tanti Test? Che Barba!
Il problema è il “costo” del testing. Fare testing è un attività onerosa, costosa, perchè è facile sbagliare o dimenticare qualcosa. Putroppo sono proprio le piccole dimenticanze che, subdolamente, rendono instabili i prodotti software. Questo vuol dire che la granularità dei test deve essere fine. Ma scrivere “molti test” è anche molto costoso, quindi bisogna ingegnarsi per impiegare saggiamente le (finite) risorse celebrali dello sviluppatore/tester.
Anche lo sviluppatore più in gamba si dimentica qualcosa, e si fa scappare dalle mani un viscido baco. Chi è senza peccato, scagli la prima pietra.
Una volta generato il bug a volte è difficile scovarlo: Turing e Dijkstra ci hanno dimostrato che i test al massimo possono dire se c’è un bug in un pezzo di codice, ma non possono assicuraci della loro assenza. Quindi generalmente la scrittura di test è più un arte che una scienza, un po’ come tutto lo sviluppo software in sé, allo stato dell’arte.
Feedback Artistico
Ma cos’ha di speciale un artista (tester) che non può essere facilmente replicato o automatizzato da un algoritmo?
Difficile dirlo, vista la scarsa conoscenza formale dell’attività cognitiva umana. Possiamo sicuramente ricondurre il tutto ad un mix di esperienza, rapidità di associazione d’idee, intuito. Di tutte queste cose, l’esperienza gioca un ruolo fondamentale, perché input per le altre, pertanto è ragionevole pensare a come poter accelerare la costruzione e la catalogazione di informazioni ordinate, dalle quali trarre conclusioni con risvolti operativi.
Da qui, la riflessione: fare del tutto per migliorare il feedback sull’andamento del codice. Questo vuol dire costruire layer di validazione (ad es. molti, moltissimi unit test leggeri e veloci, come ricorda il TDD) per consentire un refactoring indolore. Perchè il refactoring è inevitabile, anche dopo un’esauriente fase di design spesa alla ricerca della migliore architettura possibile.
Su questa impostazione (fonti dinamiche di feedback real-time), va anche l’uso oculato ed attento delle metriche software, la cui maturità è ancora bassa, ma non per questo devono essere ignorate dallo sviluppatore. Anche l’integrazione continua è, in realtà, un altro strumento di feedback in real-time: lo sviluppatore in team deve sapere se il proprio codice rompe quello degli altri, e lo deve sapere subito, altrimenti potrebbe metterci troppo tempo per eseguire le necessarie modifiche qualche giorno dopo.
Chi ha bisogno del pilota automatico?
E qui arriva il punto fondamentale: la volontà intenzionale di richiedere questi feedback (le attività “teleologiche” della cibernetica) non deve essere demandata allo sviluppatore, almeno non durante lo sviluppo. Questo perché le risorse cognitive richieste per richiamare queste azioni di monitoraggio rompono la concentrazione, così facile da perdere e così difficile da raggiungere.
In parole povere: l’esecuzione dei test, delle metriche, della valutazione delle performance, ecc., deve essere eseguita di continuo, automaticamente, mentre lo sviluppatore scrive codice.
È il sistema di controllo che deve avvertire, dolcemente, continuamente, con indicatori sempre aggiornati e disponibili, l’impatto di “ogni riga di codice” scritta dallo sviluppatore.
Developer’s Machinegun
È un po’ come usare una mitragliatrice. Le mitraglie furono inventate per far si che anche chi non sa sparare può colpire esattamente un bersaglio. Questo perchè si sfrutta l’effetto “tracciante” del flusso di proiettili. Se posso vedere rapidamente cosa ho colpito l’istante precedente, so dove posso colpire nell’istante successivo con un mio semplice, rapido ed impercettibile movimento, senza perdere concentrazione. Se gli intervalli di tempo si dilatano, la mia attenzione diminuisce perchè la sola memoria a breve termine non mi basta per valutare le giuste triangolazioni e perdo di vista l’obiettivo.
Morale: Con il giusto feedback, anche un cieco più diventare un cecchino.
A questo punto la domanda è: di quali feedback ha bisogno uno sviluppatore, per realizzare software così come un mitragliere centra rapidamente tutti i suoi obiettivi?
by Paolo Rainone
No Translations
Capita a tutti di conoscere, sul posto di lavoro, persone veramente in gamba, professionisti capaci, seri e competenti, dotati di originalità e conoscenze operative tali da rendere ogni idea progettuale una realtà concreta. Sarebbe un bel guaio per un’azienda se queste figure non esistessero, ed in particolare per quella in cui lavoriamo.
Generalmente è auspicabile che queste persone meritino di fare carriera, perchè è giusto che sia premiato chi sa fare meglio.
Più un’azienda è grande ed offre possibilità di carriera, più è facile che una persona in gamba sia notata e salga di grado, eventualmente assumendo posti di maggior prestigio ma anche di più alta responsabilità. Nessuno si opporrebbe ad una logica di questo tipo: è un principio sano e corretto.
Capita a volte, putroppo, che all’aumentare di grado quelle stesse persone si ritrovino in un ruolo non del tutto congeniale, sia perché non sono completamente preparate a gestire domini più grandi, sia perché i domini più grandi implicano attività meno consone alle proprie attitudini.
Spesso ci si trova a fare cose che non accendono la stessa passione profonda di quelle che si facevano nel vecchio ruolo.
Già, la passione: la poderosa molla che spinge tutti a fare sempre meglio sul proprio lavoro. Il piacere per le cose fatte da noi, per i bei lavori che portano la nostra firma.
Ad ogni modo, può capitare di salire di grado per altri meriti, come la simpatia, la presenza di spirito nei rapporti istituzionali, le relazioni e le amicizie di lavoro, il savoir faire. Tutte qualità importanti, senza dubbio.
In realtà più spesso accade che le nostre gesta passate proiettino sugli altri un’immagine “di successo” di noi e del nostro lavoro. L’effetto è ancora più efficace se i risultati oggettivi del nostro operato sono di difficile misurazione ed interpretazione, retti su confini labili, magari perchè il vero successo deriva dal duro lavoro delle persone “al di sotto”, che noi abbiamo semplicemente “guidato” con (presunta) sapienza e (millantata) maestria.
All’apice di questo processo paradossale, i più alti piani decisionali risulterebbero popolati da persone semplicemente non adatte al ruolo che ricoprono, eufemisticamente parlando, in realtà veri e propri incompetenti svogliati e manipolatori.
Questa logica perversa è nota come “Principio di Peter”, chiamata così dal suo autore Laurence J. Peter, a sua volta parafrasata dal celebre “Principio del Piacere” di Sigmund Freud.
Beh per fortuna questo principio è assolutamente insensato e privo di fondamento, non è vero?
Le persone che ci dirigono sanno sempre cosa fare…
by Paolo Rainone
No Translations
Al termine di un ciclo di design durato circa una settimana, relativo ad una parte di un progetto più grande, mi capitò di discutere i risultati con il PM di turno.
Egli era d’accordo con me sul fatto che la soluzione proposta risolveva il problema assegnato ma, ciò nonostante, rimase insoddisfatto del mio lavoro perché era “poco creativo”, inserendo nelle sue argomentazioni citazioni alle opere di Bertrand Meyer e Peter Coad, pietre miliari dell’OOP/OOD.
I testi citati mi erano noti da tempo, ma onestamente non vi ho mai trovato nulla che spingesse ad essere creativi anche quando non serve.
Un’ennesima conferma del fatto che se due persone sono esposte alla stessa esperienza (leggere un particolare libro, in questo caso) non è detto che traggano le stesse conclusioni.
Il problema non era di particolare complessità, ed era stato possibile modellarlo con un mapping quasi diretto tra entità evidenziate dall’analisi ed una manciata di classi.
Non c’era nessun nuovo pattern che avevo dovuto creare ad-hoc per risolvere il problema specifico, nessuna tecnologia cutting-edge, nessuna feature non documentata del compilatore da scomodare, niente che fosse degno della copertina di una rivista tecnica: solo una manciata di classi con qualche associazione.
Mi fu chiesto esplicitamente di essere più creativo, ed alla progettazione collaborò anche il PM. Dopo due mesi passati tra pesante ed estesa riprogettazione e conseguente sviluppo, la nuova soluzione (congiunta) era oggettivamente troppo complessa perché fosse portata avanti, tant’è che ritornammo all’approccio adottato nel design originale. Dopo un’ulteriore settimana e mezza era tutto pronto e si procedette oltre.
Qual è il senso di tutto questo? Ancora me lo chiedo, ma quest’esperienza vissuta mi ricorda sempre come la voglia di affermazione personale, la voglia di far vedere quanto si è bravi, di quanto si è “creativi” non sempre giova ai fini della realizzazione di un prodotto software commerciale.
Lungi dall’affermare che non debba esservi creatività nell’attività di modellazione o, peggio, che l’attività di software design non abbia un’intrinseca componente creativa, credo che tale creatività deve esprimersi con la “diligenza del buon padre di famiglia”.
Keep it simple.
by Paolo Rainone
No Translations
Il “complesso del muratore“ descrive quella particolare condizione nelle relazioni tra un lavoratore ed il suo principale, in cui il primo pensa di capirne più del secondo.
A volte, questo contesto genera un attrito così forte che ogni richiesta fatta dal PM (Project Manager, ovvero il boss) viene recepita sempre con “diffidenza” da parte dello sviluppatore, e questo introduce una calo di produttività generale non indifferente.
Nel caso in cui lo sviluppatore in questione sia tenuto in alta considerazione dagli altri colleghi, il complesso del muratore può degenerare nel funesto “Complesso di Spartaco”, in cui le prese di posizione negative nei confronti del PM si fanno sempre più accentuate e si propagano ad altri sviluppatori dello stesso team.
Generalmente queste forme di idiosincrasia estrema terminano con lo svilppatore che abbandona il progetto o con il PM che adotta misure drastiche per mantenere l’ordine nel lavoro. Spesso la seconda prelude alla prima: il PM s’incazza e Spartaco se ne va.
Morale? E’ purtroppo compito del PM, se sa fare il suo mestiere, di individuare il profilo caratteriale delle sue persone, ricordandosi spesso che gli sviluppatori più skillati hanno anche una più alta considerazione di sé.
Se il potenziale Spartaco è realmente così utile al lavoro del team, il PM avveduto deve imparare fin da subito a impare a trattare con il suo ego, ricordandosi che nelle fasi avanzate di un progetto, la dipartita di Spartaco potrebbe rivelarsi una catastrofe.
Qui si potrebbe discutere sulla reale opportunità di assumere e, conseguentemente, mantenersi buoni i potenziali Spartaco, o Programmer Hero come spesso vengono chiamati in letteratura.
E Spartaco? Non ha nessun obbligo nei confronti di chi lo gestisce? E’ davvero sempre così legittimato a fare di testa sua? Ed è sempre e solo il PM a dover venire in contro alle necessità del nostro eroe?
by Paolo Rainone
No Translations
Esistono Project Leader (PL) e Project Manager (PM) particolarmente perfezionisti, eventualmente provenienti dal mondo dello sviluppo, che hanno “vissuto” molti, “troppi” progetti soffrendo del complesso di Spartaco quando erano “dall’altra parte”.
Salendo di grado, ovviamente questi soggetti sono assolutamente convinti di fare meglio dei PL/PM che hanno incontrato fino ad allora, ed ovviamente provenendo dallo sviluppo hanno anche la pretesa di fare meglio dal punto di vista architetturale, ovvero nelle scelte di design, dando per scontato di scrivere codice più elegante ed efficiente di qualsiasi persona lavori nel suo team. Nei secoli dei secoli.
Ebbene, se tutte queste condizioni sussistono, è molto facile che il PL/PM ricada in quella condizione di continua insoddisfazione del lavoro svolto fino a quel momento dal team, per quanto quest’ultimo si sforzi di seguire le direttive.
Un class-diagram che sembrava ottimo, il giorno dopo è una “schifezza” e “deve essere riscritto”. Quella classe che risolve il problema assegnato e che aveva sempre funzionato, oggi diviene inutile (il nuovo modello non la prevede), quindi sparisce, e con lei anche tutta la sua qualità operativa.
E fin qui, nulla di strano. Se una cosa non serve, non serve.
La stranezza sta nel fatto che il soggetto colpito dalla sindrome, non riesce a star fermo un giorno. Ogni giorno è una rivoluzione, soprattutto nel design e quindi nel codice.
Dal suo punto di vista ogni giorno è buono per far vedere al mondo quali siano le più alte vette cognitive, le soluzioni più raffinate ed intellettualmente appaganti che si riescano a raggiungere spostando qualche classe (una decina), invertendo qualche associazione (7 class-diagram completamente riscritti) e rinominando qualche tipo o migliorando la code convention (il passaggio da Camel a Pascal convention, passando per un ibrido ispirato a .NET, per finire in una codifica personale dinamica ed adattiva basata sull’umore del giorno).
E poco importa se, dopo un paio di mesi passati incessantemente a cambiare sempre tutto, alla fine si ritorna al design originale. Evidentemente era una “necessaria evoluzione” e “bisognava ragionarci su”.
Inutile prendersi in giro: dal punto di vista della vita lavorativa reale, il progetto è sulla strada del fallimento.
Attenzione a chi è colpito dalla Sindrome, non esiste cura nota.
by Paolo Rainone
No Translations
Una delle frasi più significative che ho sentito da quando mi interesso di metodologie agili è la celebre “Programming Should Be Fun” di Kent Beck.
Questa focalizzazione sull’attenzione posta nel migliorare la vita lavorativa degli sviluppatori mi ha sempre colpito.
Spesso però molte persone tra quelle che adottano metodologie agili, non ritengono questo aspetto fondamentale: ciò che conta è che i progetti software vadano a buon fine, un atteggiamento condivisibile e molto pragmatico, che non mostra il fianco.
Purtroppo penso che, al contrario, questo sia il punto cardine della questione. Per garantire una più alta percentuale di successo nella realizzazione di prodotti software, bisogna rendere facile la vita del programmatore, del PM e di tutti coloro che sono coinvolti.
Secondo alcuni dati mondiali (SPR) gli sviluppatori sono tra i professionisti più stressati e soggetti al maggior numero di ore di straordinario, insieme a Medici ed Avvocati, e le relazioni con i dati sulle software failures (Jones, DeMarco, Brooks) non possono essere ignorate.
L’adagio “non ci può essere software di qualità senza qualità nella vita (lavorativa) di chi lo realizza” può essere condivisibile ma potrebbe apparire banale in quanto la qualità della vita (lavorativa) è condizione gratificante non solo per gli sviluppatori, ma per tutte le classi di lavoratori.
Il problema è che, nel mondo dello sviluppo software, il suo esatto contrario è uno scenario senza vie d’uscita.
Ovvero, la scarsa qualità di vita (lavorativa) degli sviluppatori non produce software di scarsa qualità: semplicemente non produce software.
by Paolo Rainone
No Translations
L’idea è che la tendenza al caos di un programma è funzione diretta della tendenza al caos del codice di ogni sua funzione (o metodo di classe).
La tendenza al caos del codice di una funzione è diretta conseguenza della possibilità che la sequenza di rami d’esecuzione di cui è composta la funzione in un contesto dinamico, tende a cambiare da una build all’altra, a parità di contesto esecutivo.
Percorsi Esecutivi
Spieghiamo meglio questo concetto. Staticamente, una funzione è costituita da un insieme di possibili percorsi esecutivi, definiti rami esecutivi (execution branches) o punti di sequenza (sequence points).
Ora ci interessa valutare il comportamento dinamico del sistema, ovvero in contesto d’esecuzione perché il danno maggiore (apportato dal caos) si ha quando il comportamento esecutivo di una funzione è differente da quello atteso (ricavato dalla sua definizione statica), a parità di contesto esecutivo.
Variazione di stato dei Test
Se pensiamo ad un test definito, quindi con un contesto prestabilito e codificato, sarebbe interessante valutare il cambiamento di stato del test di una funzione, anche se né il test né la funzione testata vengono modificati.
In particolare, è interessate osservare e comprendere le relazioni che intercorrono tra metodi remotamente invocati dalla funzione in oggetto, e cosa le succede al variare di qualcosa di valutato come “estremamente lontano”, o di qualcosa con il quale “non dovrebbe avere niente a che fare” (per quanto si ricordi).
Contesto Esecutivo
Per far questo, fissiamo l’insieme di parametri di ingresso ed i valori delle variabili non locali da cui la funzione è dipendente.
Con questo s’intende che, fissato un contesto di esecuzione di una funzione, come farebbe un test unitario, i rami enumerati staticamente in realtà compongono una sequenza potenzialmente più lunga.
Questo perchè in un contesto dinamico sono da tenere in conto anche le ripetizioni di opportuni rami, al pari dell’eventualità che la sequenza eseguita sia più corta, in quanto le selezioni e la generazione di eccezioni possono accorciare l’effettivo percorso esecutivo.
by Paolo Rainone
Other Languages:
L’input che ha dato il via all’intero ragionamento, parte da un’osservazione che chiunque abbia sviluppato secondo la metodologia Test Driven Development (TDD) ha incontrato, prima o poi.
Consideriamo per un attimo di non impiegare gli opportuni pattern di refactoring altrimenti necessari.
Giorno 1
Definiamo il test per una funzione A;
Il test passa (green bar, secondo la terminologia di Beck).
Giorno 10
Dopo aver usato la funzione A in diversi punti del codice, ci accorgiamo che A ha bisogno di una leggera variazione, ad esempio un nuovo parametro in ingresso, impiegato opportunamente nel codice.
Modifichiamo di conseguenza la funzione e tutte quelle che la invocano.
Questa modifica al resto del programma la eseguiamo senza seguire un particolare pattern di refactoring, come premesso. Questo perchè gli errori di codifica possono sfuggire a tutti, ed in questa sede c’interessa valutare proprio quegli errori indotti dalla distrazione, o dalla naturale imprecisione dell’uomo.
Un Refactoring applicato male è peggio di un refactoring non applicato per niente.
Il test di A passa anche stavolta, altra green bar (GB).
Giorno 20
Ci serve un’altra funzione, chiamata B, che usa A al suo interno.
Testiamo B ed anche A, con esito positivo (GB).
Giorno 180
Dopo qualche mese passato a costruire la nostra applicazione, in cui abbiamo realizzato centinaia d’altre funzioni che usano A e B, ci accorgiamo che ci serviva un altro parametro in B.
Modifichiamo B e (ovviamente) tutto il codice che la invoca, altrimenti non compiliamo.
A questo punto, il test di A non passa più: red bar.
Il Punto
Strano? In realtà questo comportamento è possibile ed è decisamente ricorrente, in quanto anche se A non invoca direttamente B, essa può dipendere indirettamente tramite tecnologie correlate pertinenti ad altri domini architetturali, come un database in comune.
Tralasciando la complessità esigua dell’esempio, personalmente comportamenti di questo tipo mi hanno indotto ad alcune domande:
1. Cosa ha fatto variare il comportamento del test di A?
2. Se non avessi usato un test, avrei potuto comprendere in tempo le ripercussioni che B ha avuto su A e su tutte le funzioni che usano A, nonostante le relazioni di chiamata diretta non avrebbero evidenziato nulla?
3. Se avessi applicato correttamente il refactoring, avrei dovuto ragionevolmente attendermi un’altra green bar anche al giorno 180?
4. Senza test, mi sarei accorto in tempo o “troppo tardi” del “caos” introdotto nel codice da una mia maledettissima svista?
5. Se la modifica “caotica” fosse stata introdotta da un mio collega disattento (o ignaro del contesto perchè mi ero dimenticato di documentare del codice), avrei avuto la stessa “fortuna” nell’accorgermi dell’errore anche senza test?
Fortuna, sviste (maledette), colleghi maldestri, stanchezza, refactoring applicati male…sono davvero cose da “lamer“, oppure sono elementi che ricorrono anche tra i cutting-edge senior developer?
by Paolo Rainone
No Translations
Avere tutto chiaro, prima ancora di farlo. Obiettivamente è uno scenario desiderabile.
Del resto chi si tufferebbe in un’impresa incerta, dall’esito impreciso e dalle modalità tutte da definire?
Ancora peggio: chi affiderebbe la soluzione di problemi in ambito lavorativo ad un ingegnere che non ha un’idea chiara di come dovrà agire?
Informazione e Conoscenza
Chi accetterebbe di divenire un professionista di una disciplina che non ha certezze?
È per questo che durante l’intero iter del training di un progettista o di uno sviluppatore software, tutte le lezioni impartite, dirette o indirette, tendono ad infondere una certa sicurezza nelle tecniche proposte.
Ad ogni modo è appunto l’incertezza della propria conoscenza, o (se si preferisce) la certezza della propria ignoranza, per citare Bukowsi, che agli inizi della carriera ci spinge ad apprendere, quasi in maniera ossessiva.
Si apprende nella speranza che la disciplina scelta ci aiuti a divenire professionisti e, per induzione, a divenire persone più mature.
Donne e uomini che ad un certo punto della propria vita potranno dire di conoscere realmente qualcosa, di avere consapevolezza del proprio ambito, di avere delle certezze profonde.
Paure Paradossali
Paradossalmente è come se nei primi anni di pratica, l’assoluta inconsapevolezza di quanto sia incerto fare software sia molto bassa, mentre è alta la voglia di apprendere (e di far vedere cosa si è appreso). Le nuove iniziative dagli esiti non perfettamente decidibili a priori ci preoccupano poco.
Con gli anni la situazione tende ad invertirsi, fino a raggiungere casi patologici. In certi soggetti, la necessità viscerale di dominare tutto ciò che è incerto causa eritemi, orticaria e stati di allucinazione spontanea. Questi sintomi sono tanto più gravi quanto più è forte la convinzione di non aver più nulla da apprendere.
Le paure inconsce dell’incertezza, dell’ignoto, della morte (che simboleggia l’ignoto più assoluto), sono alla base di tutte le paure dell’uomo e di tutti i suoi comportamenti irrazionali, aggressivi e bellici.
La stessa paura ha indotto, nel software, con il tempo a adottare soluzioni sempre più protettive, preventive, che progressivamente sono divenute troppo costose da mantenere, producendo il risultato opposto, ovvero quello di far fallire i progetti per mancanza di budget, oppure di fallire perché si voleva (doveva) essere troppo sicuri di fare bene.
Lungi dal considerare soluzioni come l’epicurea “uscita perfetta”, magari pensate specificatamente come clausola liberatoria nei contratti software, probabilmente dovremmo prenderci più tempo per riflettere sulla validità delle nostre conoscenze.
Quando possiamo dire di aver “appreso la lezione”, in maniera tale da sedare la paura dell’ignoto? Quando si può essere certi che la “lezione appresa” sia veramente tutto quello che potevamo comprendere da un’esperienza passata?
In questa direzione vanno interessanti pratiche Agili, come Reflections e Retrospecitives, preziose occasioni per fermarsi un attimo ed analizzare il proprio operato. Le prime si concentrano su cicli di sviluppo brevi, chiamati spesso iteration o sprint, le seconde sono più profonde e generalmente adottate al termine di un progetto.
Per citare le parole di Ronald Lang, illustre psichiatra contemporaneo,
“L’insieme di cosa facciamo e pensiamo è limitato da cosa non riusciamo a notare. Dato che non riusciamo a notare ciò che non notiamo, possiamo fare poco per cambiare, finché non notiamo che il non riuscire a notare plagia i nostri pensieri e le nostre azioni”.
Il gioco della vita
Se la chiave fosse smettere di dover dimostrare obbligatoriamente agli altri, ed a noi stessi, di saper dominare tutto e subito e ci rendessimo conto che solo facendo possiamo fare?
Se fossimo finalmente onesti con noi stessi, ammettendo che non sempre è dato di sapere a priori quale sarà la soluzione giusta per ogni problema, o parte di problema?
Del resto, se ci soffermiamo un attimo, è un po’ come il gioco della vita: nessuno ci insegna le regole ma siamo costretti a giocare e solo giocando impariamo a vincere.
Niente Scuse
Questo approccio non deve essere preso come una semplice scusa per coprire le proprie mancanze, sarebbe troppo facile.
La proposta presa di coscienza ha uno scopo principale: liberarci dal quel carico opprimente, quello stress psicologico che spesso attanaglia chi è chiamato a dare una risposta certa ad un problema tecnico complesso che non si è mai incontrato prima.
Nel mondo dello sviluppo software, caratterizzato da una complessità elevata e da un’evoluzione fulminea, è molto facile incontrare problemi mai incontrati prima, includendo i problemi noti applicati in contesti completamente sconosciuti.
Il Nuovo Rinascimento
Probabilmente anche questa è una ragione che mi ha spinto ad avvicinarmi alle metodologie agili, che fanno proprio il credo di gestire l’incertezza con il buon senso, buon senso derivante dal soffermarsi sulla comprensione profonda dell’agire e del pensare umano.
Un’ennesima formulazione del rinascimentalissimo “L’uomo al centro di tutto”. L’uomo, con tutti i suoi limiti e le sue caratteristiche uniche, le sue potenzialità infinite.
In fin dei conti, per risolvere problemi, i computer hanno ancora bisogno dell’uomo che li programma e ne avranno bisogno ancora per molto. Perché dunque non concentrarci sull’uomo chiamato a comprendere e risolvere, piuttosto che sulla macchina chiamata ad eseguire?
Non me ne voglia il buon vecchio HAL.
by Paolo Rainone
No Translations
Se due persone vivono lo stesso evento, non è detto che traggano le stesse identiche conclusioni: tutto dipende dalla storia personale, dal background culturale, dalla preparazione tecnica, dall’esperienza in un particolare campo, da quanti campi differenti hanno toccato, dall’innata sensibilità personale, dalle basi religiose, sessuali, razziali, sociali, politiche, ecc.
Ciononostante, è necessario trarre il massimo insegnamento da ogni evento che ci coinvolge, o al quale assistiamo. Ecco alcune buone regole per trarre il massimo dalle nostre esperienze:
- Non dimenticare il contesto di realizzazione di un progetto;
- Non trarre conclusioni affrettate, paragonando scelte effettuate in un particolare contesto con altre analoghe fatte in contesti differenti (più facile/difficile/più soldi/più persone/momento storico differente/tecnologie di base meno evolute/ecc.);
- Non perdere la storia di tutte le scelte fatte;
- Non perdere troppo tempo a tener traccia delle scelte fatte. L’utilità della scrittura è inversamente proporzionale a quanto tempo ci sottrae al raggiungimento del nostro obiettivo primario: scrivere codice.
Ovviamente è necessario mantenere una soglia minima di tempo da riservare ad annotazioni varie, ma con l’accorgimento di prenderle durante lo svolgimento del lavoro stesso, e con un minimo sforzo, tale da non distogliere/deconcentrare il programmatore dal suo scopo originale: scrivere codice.
by Paolo Rainone
No Translations
Mi è capitato di incontrare, neanche tanto di rado, delle persone nel campo dello sviluppo software che sapevano parlare molto bene di (sviluppo) software, dotate di una buona dialettica, e che davano effettivamente l’impressione di sapere il fatto proprio.
Certamente delle persone dotate di una spiccata intelligenza, se è vero che i centri del linguaggio sono la quinta essenza delle potenzialità del cervello umano, e che la formulazione di concetti complessi è intimamente legata con talune aree cerebrali.
Tutto molto vero, tranne un piccolo particolare: fare software non è come parlarne.
(1) Per parlarne è sufficiente aver letto un buon numero di pubblicazioni, meglio se chiare e ben scritte (quindi non questo blog).
(2) Per fare software bisogna aver passato buona parte della propria vita di fronte ai monitor, con la testa concentrata sull’atto di dominio del caos.
La prima capacità senza la seconda, consente di parlare bene (con le parole degli altri), ma manca di quella fondamentale materia che risolve velocemente ed efficacemente tutti i problemi: l’esperienza personale.
Il successo di un progetto software è ancora nelle mani delle persone che hanno una reale, efficace, esperienza maturata nel corso degli anni e nel corso di molti progetti.
Morale?
(a) Scrivere tanto codice (attività principale);
(b) di tanto in tanto prendersi la briga di analizzarne la qualità (magari insieme agli altri colleghi);
(c) mai smettere di chiedersi se si poteva fare di meglio (e si può sempre fare di meglio);
(d) mai smettere di cercare se qualcun’altro ha fatto di meglio (c’è sempre qualcuno che l’ha fatto meglio).
Banale? Beh sono i consigli della Nonna…
by Paolo Rainone
No Translations
Certo si apprende anche dagli sbagli degli altri, è questa la filosofia degli istituti di formazione, e dei corsi di training in generale. Questo approccio è ovviamente condivisibile per la riduzione dei tempi di apprendimento e per il ridotto impatto degli errori commessi dall’inesperienza iniziale.
C’è da dire però che una lezione impartita da un’insegnate spesso lascia una traccia cognitiva meno incisiva di una ricevuta sul campo.
Nelle attuali necessità del mondo dello sviluppo software, è nel momento in cui le nozioni, le teorie e le ipotesi si applicano a problemi concreti nel lavoro quotidiano che ci si rende conto di cosa funziona e cosa no.
Se si è sufficientemente appassionati del proprio lavoro, l’errore personale è un marchio a fuoco, che spesso fa cambiare filosofia di vita, apre gli occhi, influisce sulla dieta o sulla marca di sapone.
L’errore personale, quando è di una certa gravità e per lo più imputabile effettivamente a noi stessi, è un trauma che genera catarsi (sempre che si abbia sufficiente consapevolezza, introspezione, ed onestà intellettuale tale da riconoscere i propri errori). Se chi legge è il coordinatore di un team (project manager?), allora la dose di onestà intellettuale richiesta è almeno tripla.
Il problema è che, nella realizzazione di un progetto software, le responsabilità sono imputabili all’operato di diverse persone.
Per quanto si voglia dare la colpa a Murphy, e ad alla sua bistrattata presunta legge, se il prodotto non funziona proprio quando viene il committente per verificare una milestone, la responsabilità è innanzitutto di chi ha gestito il progetto.
Solo lui ha il dovere di prendere provvedimenti e di prevedere i tempi, ovvero di agire almeno nei seguenti casi:
• gli sviluppatori non fanno il loro dovere;
• sostituire tempestivamente gli sviluppatori che si ritiene inefficaci;
• gli sviluppatori fanno il loro dovere, ma non è abbastanza;
• tutti fanno il loro dovere ma non è ancora abbastanza;
• tutti fanno i salti mortali, ma il codice non ne vuole sapere di funzionare;
• invitare il cliente in un altro giorno, o spostare l’appuntamento preso, motivando un precario stato di salute generale (tifo o colera andranno benissimo);
• fare un bel corso di project management (soluzione non risolutiva);
• abbandonare il progetto (scelta che va contro l’autostima, la reputazione ed il conto in banca).
by Paolo Rainone
No Translations
A volte, quando si è alle prese con il proprio computer, per lavorare o per svagarsi, capita di vivere un esperienza strana.
Vi è mai capitato di iniziare un task, magari metter su un sito, o provare un nuovo SDK, o quella nuova tecnica che abbiamo letto da qualche parte qualche giorno prima, ed immergersi a tal punto da perdere completamente la cognizione del tempo?
La prima volta che mi accorsi di un effetto simile, fu quando giocai per la prima volta a Civilization, il capolavoro di Sid Meyer.
Iniziai alle 21 e, senza rendermente conto, finii di giocare alle 5 del giorno seguente. Incredibile. Non mi accorsi di niente per circa nove ore.
In realtà se non avessi notato un leggero fastidio dovuto all’abbassamento della temperatura, e l’albeggiare che faceva capolino dalla finestra, avrei tranquillamente continuato a giocare.
Spesso, quando si programma, capita di essere abbastanza sicuri di riuscire a terminare un task entro poco tempo, un paio d’ore al massimo.
In realtà, a volte le cose si complicano e, senza accorgercene, l’intera giornata vola via.
Quante volte è capitato di ritornare per un attimo sulla terra grazie all’intervento di un collega che avvertiva “è ora di pranzo”. Un ritorno non sempre apprezzato, nonostante la buonafede: in effetti se il problema incontrato è di una certa complessità (quindi di un certo fascino), magari ci facciamo un pensierino sul saltare questo indesiderato pasto…magari cerchiamo di ritardarlo ancora un altro po’, pensando: “tanto tra un po’ finisco…”.
Le ultime parole famose.
La giornata passa via come una folata di vento, e noi non ce ne siamo neanche accorti.
Ma perchè succede tutto questo?
Come mai i computer hanno questo potere di irretire la nostra attenzione a tal punto, da gettarci in un universo parallelo, dove lo spazio ed il tempo seguono direttrici differenti?
E’ come se per noi il tempo viaggiasse più lentamente, pertanto al di fuori del nostro sistema “io+mio_computer”, visto dai nostri occhi il tempo scorre più velocemente.
E’ forse troppo difficile usarli? Quindi le risorse cerebrali che ci richiedono per essere controllati sono così tante da necessitare una sorta di spockiana “fusione mentale”?
Beh, lasciando da parte le situazioni palesemente piacevoli, come giocare ad un videogioco, nelle situazioni di lavoro questo “fatto” ovviamente ha risvolti decisamente più seri.
Probabilmente i due casi, ovvero l’ occupazione piacevole (giocare ad un videogioco) e l’occupazione “seria” (lavorare, e più specificatamente sviluppare), hanno origini diverse, anche se non completamente.
Quando giochiamo rientriamo nel fenomeno della “fuga dalla realtà“, ovvero siamo noi a non voler smettere, e questo accade non solo con i computer. La stessa cosa accade anche guardando un bel film, o leggendo un buon libro, tutte cose che ci portano in “mondi distanti” che ci piacciono molto, ci danno emozione.
Integrare un nuovo SDK appena rilasciato, le cui funzionalità sono ancora non completamente documentate, oppure talmente tanto estese da far perdere la testa agli stessi sviluppatori, potrebbe non essere sempre un esperienza piacevole, anche se sulle prime potrebbe risultare stimolante.
Pertanto, certamente non parlerei di “fuga dalla realtà” nei casi lavorativi, benchè le eccezioni potrebbero non mancare.
Da un lato, certamente i computer di oggi sono ancora troppi difficili da usare, e questo è vero anche per un programmatore esperto.
Inutile prendersi in giro, visto che i principali tool che i programmatori usano sono anche loro affetti da problemi di lentezza, bug software e comunque spesso caratterizzati da una complessità tale che viaggiano sempre al limite della differenza fra una feature e un bug.
Inizialmente pensavo che le “micro attese” dovute alla lentezza del feedback del software usato (caldeggiata dalla lentezza dell’hardware) fossero una parte importante della verità.
Tutta quella catena di piccole attese, inanellate click dopo click, compilazione dopo compilazione, è come se dilatassero la nostra sensazione del tempo.
Inizialmente la nostra mente viaggia ad una velocità superiore, poi però si deve adattare alla marcia imposta dal sistema che sta usando. Non può farci niente, è sempre l’uomo che si deve adattare alla macchina, lei è troppo stupida per farlo.
E’ così facendo sprechiamo risorse cerebrali, che ovviamente prima o poi si esauriscono.
Spesso siamo chiamati a gestire task particolarmente complessi, ma il feedback che riceviamo dagli strumenti a nostra disposizione è scandalosamente limitato. Questa scarsa sensazione di controllo, che a volte non è solo una sensazione, è spesso tra le cause del nostro problema.
Quando qualcosa continua a non funzionare, sfuggendo al nostro controllo, ci capita di entrare in una sorta di busy-waiting loop.
Velocemente ci ritroviamo invischiati nel nefasto ciclo “scrivo-questo”, “compilo”, “non funziona!”, “provo-quest’altro”, “ricompilo”, ecc…
In poche parole la scarsità di informazioni, la lentezza dei computer, la presenza di bug, il tutto unito alla voglia/necessità di riuscire ci fa perdere la cognizione del tempo.
Prendere coscenza di questo comportamento, probabilmente può migliorare lo stato delle cose e magari non ci farà saltare i pasti.
Tanto è inutile.
by Paolo Rainone
No Translations
Nel 1993, il pianeta Marte fu invaso da oscure forze demoniache che annientarono brutalmente qualsiasi entità senziente, compreso il robottino PathFinder.
Contemporaneamente la vita sulla Terra fu scossa e profondamente modificata dall’avvento di Doom, il first-person-shooter (FPS) così coinvolgente e tecnologicamente avanzato da scuotere l’anima di ogni malcapitato giocatore.
Un concentrato di tecnologia software talmente elevato che ridefiniva tutti gli standard in fatto di programmazione di videogiochi, rappresentando un salto generazionale come pochi se ne sono visti nella storia.
La principale mente realizzatrice di quell’opera d’arte software era John Carmack, classe 1970, che senza un particolare titolo di studio oltre il suo diploma si scuola superiore ha inventato un genere, quello degli FPS, ed ha saputo farlo evolvere fino ai giorni nostri, senza mai abbandonare le sue creature, e senza mai smettere di programmare e di innovare il suo ed il nostro mondo.
Il mito lo vuole appassionato di Heavy Metal, collezionista di Ferrari e spade medioevali, progettista e realizzatore di razzi teleguidati (con la sua Armadillo Aerospace) e convinto sostenitore dell’open source. Carmack è probabilmente la personalità più autorevole che negli ultimi anni ha parlato al grande pubblico di entropia del codice, con la sua famosa frase “Fight the code entropy”, così come ce l’ha riportata Michael Abrash.
Benché non mi sia nota una sua personale spiegazione di ciò che intendeva effettivamente dire, probabilmente si può fare qualche congettura dal contesto in cui Abrash la riporta.
Nell’esprimere il modus vivendi e la forma mentis di un buon programmatore di videogiochi, che per definizione deve essere dotato di capacità superiori alla media, egli ammonisce:
“Non sentirti mai troppo comodo. Aspira all’eccellenza. Combatti quella soddisfatta sensazione che hai del tuo codice, e domanda[ti] costantemente come migliorare [il codice e te stesso]. Combatti l’entropia del codice”.
Per certi versi è come se la presa di coscienza che l’inevitabile degradamento del codice dovesse essere combattuto prima di tutto con una rigida disciplina personale, prima ancora che con l’uso di strumenti atti ad evidenziare il problema e risolverlo in maniera sistematica.
Il grave peso morale dell’impatto dell’entropia nella scrittura di codice, viene avvertito come una minaccia da combattere con l’attitudine, con la fede nella propria disciplina, con l’anima prima ancora che con il corpo.
Questo è lo spirito di un vero guerriero.
by Paolo Rainone
No Translations
Come mai il caos s’impossessa del nostro codice? È un processo spontaneo?
In un certo senso è un processo naturale, in quanto è nella natura dell’uomo tendere a dimenticare i dettagli, man mano che il numero di dettagli da ricordare aumenta.
Un programma è un enorme insieme di dettagli infinitesimi, ed i dettagli nel codice di un programma ne rappresentano la sua utilità a risolvere il problema assegnato.
Non è solo una questione di scelte iniziali di design, del giusto algoritmo, di invertire una riga con un’altra, o scegliere un intero a 16 bit al posto di uno a 32 bit.
Il problema fondamentale si verifica quando si deve apportare una modifica a codice già scritto, per risolvere un inevitabile problema sorto all’ultimo minuto, un’inezia, una leggera perdita di precisione dopo la decimillesima interazione nella somma di due float.
Una rara occorrenza, difficilmente prevedibile in fase di progettazione, che si risolve facilmente e con poco in fase di codifica, senza neanche dover scomodare il refactoring, aggiornare i test per quella funzione, sincronizzare la documentazione per quel metodo o, peggio, senza sincronizzare i modelli di design e di analisi (senza neanche minimamente pensare ai requisiti).
Una banalità in fondo; la deadline è vicina e ci sono problemi più importanti da risolvere e non c’è tempo da perdere per le banalità.
Le risorse mnemoniche di un individuo normale sono limitate, nel senso che hanno un limite, e generalmente si riconfigurano per gestire i problemi più importanti ed impellenti: è l’istinto di sopravvivenza.
Ma “il sonno della ragione genera mostri” e neanche il SuperDeveloper(tm) può farci niente, ecco perché è destinato a soccombere.
Lo sforzo maggiore è tutto volto alle priorità maggiori, e non potrebbe essere altrimenti visto che, come accennato, le energie delle risorse umane, quelle che compiono gli sforzi di programmazione, sono limitate. Ecologia della Programmazione.
Tutto il codice che rimane da scrivere, lo stress, la deadline, le priorità, agiscono come forze non conservative sul lavoro del programmatore, premesso che il lavoro del programmatore è uguale allo sforzo intellettuale moltiplicato per il codice scritto. Meccanica del Codice.
Ebbene proprio quella leggera, piccola variazione innocente, si ripercuote su tutto il codice che invoca la funzione appena modificata.
Scotty probabilmente l’avrebbe definita come una fluttuazione quantica all’interno del tessuto spazio-temporale sul quale giace il nostro programma.
Tutte le migliaia, milioni di relazioni di codice già stabilite e che fino a quel momento trovavano una loro armonia, ora vengono lievemente smosse.
Armonia perturbata, equilibrio rotto.
Senza che nessuno se ne accorga, almeno nell’immediato. Ed essendo così piccolo, l’evento generatore tende ad essere dimenticato molto velocemente. L’origine della variazione che porterà all’inevitabile decadimento del codice si perde nel codice stesso. Cenere alla Cenere.
È un po’ l’effetto della celebre farfalla di Lorenz, che sbattendo le ali in Brasile provoca un uragano in Texas qualche tempo dopo.
È un processo naturale, spontaneo, irreversibile. L’entropia del codice tende ad aumentare, riga dopo riga, funzione dopo funzione, build dopo build.
Collateralmente, questa è un’implicita affermazione che il bug più grande si annida “tra la tastiera e la sedia”: potenzialmente facile da individuare ma impossibile da rimuovere completamente. Diagnosi immediata, prognosi riservata.
Ogni universo di codice (programma) ed il caos che vi domina hanno la stessa origine. Le due siamesi parti della stessa banconota: solo se entrambe presenti, il tutto ha valore.
A meno di una improbabile creazione di perfetti automi programmatori da parte dell’uomo, possiamo solo migliorare il modo in cui le scommesse sono formulate e truccare la moneta per far pesare meno un lato dell’altro.
Il lato che ci interessa, ovviamente.
by Paolo Rainone