L’EVOLUZIONE DEI LINGUAGGI DI PROGRAMMAZIONE:...

14
MONDO DIGITALE •n.4 - dicembre 2003 1. LINGUAGGI … MA SOLO DI PROGRAMMAZIONE? N el gergo informatico comune, quando si parla di un “linguaggio”, si fa di solito ri- ferimento a un linguaggio di programmazio- ne. Tutti sanno che esistono linguaggi di spe- cifiche, linguaggi di analisi ecc., ma alla do- manda: “Che linguaggio usate?” tipicamente la risposta è “Java” oppure “C” o ancora “C ++ ” e così via. Spesso, questa è stata defi- nita come un’anomalia, un limite per il siste- ma di sviluppo. Può darsi. Di fatto, l’utente fi- nale vuole un sistema software che funzioni. Analisi, progetto e tutte le fasi precedenti la codifica sono certamente importantissime a questo scopo. Tuttavia, solo la programma- zione fornisce un sistema funzionante, ovve- ro ciò che ha un valore diretto e tangibile. Posto in altri termini, mentre esistono pro- dotti software costruiti solo sul codice, ma- gari costruiti molto male, ma tant’è funzio- nanti e rispondenti ai requisiti del cliente, non esistono prodotti software costruiti solo con i documenti di analisi, di progetto ecc., e tramite i linguaggi di riferimento per tali fasi. Pertanto, e senza nulla voler togliere ai lin- guaggi non di programmazione, in questa trattazione ci si concentrerà sui linguaggi di programmazione (Figura 1). 2. CARRELLATA STORICA Come si legge in tutti i libri di introduzione al- la programmazione, nei primi calcolatori, il programma era definito da circuiti elettrici: veri e propri collegamenti fisici. Si passò poi ai codici binari e ai linguaggi assemblativi a essi associati, ciascuno dei quali si riferiva in modo quasi completamente univoco a speci- fici elaboratori. Cambiando elaboratore, di solito, cambiava anche il linguaggio. Il primo sostanziale passo in avanti nella programmazione fu a cavallo tra gli anni ’50 e gli anni ’60 quando si passò ai cosiddetti “linguaggi di alto livello”, ovvero a linguag- gi che esprimevano la computazione da fa- re in modo procedurale, per esempio, il FORTRAN (FORmula TRANslation) [1] e il CO- BOL (Common Business-Oriented Langua- ge) [25], o in modo funzionale, per esem- È meglio usare FORTRAN o Basic? C o Pascal? C ++ o ADA? Java o C#? Generazioni di informatici hanno combattuto battaglie all’“ultimo sangue” per difendere il “loro” linguaggio di programmazione, adducendo le più sva- riate motivazioni per giustificare la scelta. Nei 50 anni di storia dei linguaggi di programmazione, la scelta tra “cambiare linguaggio” e “cambiare il lin- guaggio” sembra sia ricaduta sulla seconda opzione. In questo articolo, si analizza lo sviluppo dei linguaggi con riferimento ai loro processi di sviluppo. Giancarlo Succi L’EVOLUZIONE DEI LINGUAGGI DI PROGRAMMAZIONE: ANALISI E PROSPETTIVE 39 3.2

Transcript of L’EVOLUZIONE DEI LINGUAGGI DI PROGRAMMAZIONE:...

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1. LINGUAGGI … MA SOLODI PROGRAMMAZIONE?

N el gergo informatico comune, quando siparla di un “linguaggio”, si fa di solito ri-

ferimento a un linguaggio di programmazio-ne. Tutti sanno che esistono linguaggi di spe-cifiche, linguaggi di analisi ecc., ma alla do-manda: “Che linguaggio usate?” tipicamentela risposta è “Java” oppure “C” o ancora“C++” e così via. Spesso, questa è stata defi-nita come un’anomalia, un limite per il siste-ma di sviluppo. Può darsi. Di fatto, l’utente fi-nale vuole un sistema software che funzioni.Analisi, progetto e tutte le fasi precedenti lacodifica sono certamente importantissime aquesto scopo. Tuttavia, solo la programma-zione fornisce un sistema funzionante, ovve-ro ciò che ha un valore diretto e tangibile.Posto in altri termini, mentre esistono pro-dotti software costruiti solo sul codice, ma-gari costruiti molto male, ma tant’è funzio-nanti e rispondenti ai requisiti del cliente,non esistono prodotti software costruiti solocon i documenti di analisi, di progetto ecc., etramite i linguaggi di riferimento per tali fasi.

Pertanto, e senza nulla voler togliere ai lin-guaggi non di programmazione, in questatrattazione ci si concentrerà sui linguaggi diprogrammazione (Figura 1).

2. CARRELLATA STORICA

Come si legge in tutti i libri di introduzione al-la programmazione, nei primi calcolatori, ilprogramma era definito da circuiti elettrici:veri e propri collegamenti fisici. Si passò poiai codici binari e ai linguaggi assemblativi aessi associati, ciascuno dei quali si riferiva inmodo quasi completamente univoco a speci-fici elaboratori. Cambiando elaboratore, disolito, cambiava anche il linguaggio.Il primo sostanziale passo in avanti nellaprogrammazione fu a cavallo tra gli anni ’50e gli anni ’60 quando si passò ai cosiddetti“linguaggi di alto livello”, ovvero a linguag-gi che esprimevano la computazione da fa-re in modo procedurale, per esempio, ilFORTRAN (FORmula TRANslation) [1] e il CO-BOL (Common Business-Oriented Langua-

ge) [25], o in modo funzionale, per esem-

È meglio usare FORTRAN o Basic? C o Pascal? C++ o ADA? Java o C#?

Generazioni di informatici hanno combattuto battaglie all’“ultimo sangue”

per difendere il “loro” linguaggio di programmazione, adducendo le più sva-

riate motivazioni per giustificare la scelta. Nei 50 anni di storia dei linguaggi

di programmazione, la scelta tra “cambiare linguaggio” e “cambiare il lin-

guaggio” sembra sia ricaduta sulla seconda opzione. In questo articolo, si

analizza lo sviluppo dei linguaggi con riferimento ai loro processi di sviluppo.

Giancarlo Succi

L’EVOLUZIONEDEI LINGUAGGIDI PROGRAMMAZIONE:ANALISI E PROSPETTIVE

39

3.2

pio, il LISP (LISt Processing language) [24].A quel tempo, i problemi significativi non ri-guardavano tanto l’organizzazione del pro-cesso di produzione, di solito lasciato nellemani di pochi esperti, quanto la comprensio-ne e la memoria di ciò che veniva sviluppatoall’interno della stessa comunità degli svi-luppatori. Di qui, la necessità di trascrivere lacomputazione in un formalismo familiare aiprogrammatori dell’epoca; era il tempo delleastrazioni: formule matematiche (FORTRAN),astrazioni logiche (LISP) o transazioni econo-miche (COBOL)1. Inoltre, la diffusione e la di-versificazione del mercato dei calcolatorielettronici rese pressante il bisogno di scrive-re programmi che funzionassero su più piat-taforme di calcolo.Presto ci si accorse che questo non bastava(fine anni ’60 e primi anni ’70). I programmidiventavano più grandi e richiedevano la col-laborazione di più persone, anche più gruppidi persone. Occorreva strutturare il processodi sviluppo per renderlo più organico. Pren-dendo a prestito concetti e terminologie dal-le teorie di management in voga all’epoca, enei decenni precedenti per essere precisi, inprimis una versione molto statica del Fordi-smo [3], ci si concentrò sull’idea di organizza-re il processo di sviluppo in moduli indipen-

denti con interfacce chiare e componibili. Sidiffusero concetti quali la programmazionestrutturata, il data hiding e l’incapsulamen-to. Nacquero l’ALGOL [10], il C [21], il Pascal[20], il Modula 2 [35] e l’Ada [15]: anche ilFORTRAN fu fatto evolvere in questo senso.Il processo di produzione modulare nella suatraduzione informatica, il modello di svilup-po “a cascata”, dominò gli anni ’70 e i primianni ’80. I limiti di questo modello, soprattut-to la sua incapacità di gestire la flessibilità ri-chiesta dalla produzione del software, co-minciarono a essere evidenti verso la metàdegli anni ’80. Ci furono piccole variazioni dirotta, come i modelli di sviluppo “a V”, masostanzialmente il modello modulare e gli as-sociati linguaggi strutturati rimasero predo-minanti. L’idea guida era che la mancanza diprecisione, e l’incertezza che la causava, po-teva e doveva essere risolta a priori, tramitespecifiche più accurate e circostanziate.Negli anni ’80 la comunità scientifica acquisìla consapevolezza che i problemi non eranosolo legati alla carenza umana nelle attività didefinizione del sistema, ma anche all’esisten-za di una zona di ombra intrinseca allo svilup-po di un qualunque sistema software, chenon permetteva di definire in modo completoe corretto fin dall’inizio le caratteristiche cheil sistema software avrebbe avuto alla fine.Il punto di partenza per lo sviluppo di un si-stema software sono, in effetti, bisogni veri opercepiti come tali.Ma tanti di questi bisogni si esprimono non in

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

0

0

0

1

40

FIGURA 1Evoluzione dei

linguaggi

Processo Bisogno Linguaggio

1950

1960

1970

1980

1990

2000

Primi tentativi di “ordine”nello sviluppo

Comprensibilità e portabilità del codice,per sostenere la sua evoluzione

Organizzazione “industriale”dello sviluppo dei sistemi software

Impossibilità di definire in modopreciso il sistema da sviluppare

Sviluppo e distribuzione moltorapidi e orientati ai sistemi

di comunicazione

Waterfall, a “V”, ...

Incrementale, Spirale, ...

Metodologie agili

Linguaggi assemblativi

Linguaggi di alto livello

Linguaggi strutturati

Linguaggi orientati agli oggetti

Linguaggi per lo sviluppodinamico

1 Si tralascia di menzionare altri linguaggi che, purmolto popolari all’epoca, direbbero molto poco allettore di oggi.

forma completamente razionale e comunica-bile univocamente, ma semplicemente comeun “senso di bisogno”. Così lo sviluppo parteda requisiti generici e solo gradualmenteevolve verso modelli maggiormente definiti.La comprensione di questa problematicapermise un salto nelle modalità di sviluppodel software. La suddivisione modulare la-sciò il posto a sviluppi del software in ma-niera incrementale, per così dire, “a piccolipezzi”, in modo che si potesse usare ognu-no di questi pezzi per calibrare lo svilupposuccessivo. Facendo un’analogia con la co-struzione di una casa, è come se ci si fosseconcentrati a costruire una casa facendoprima la costruzione generale e poi una ca-mera alla volta dalle pareti fino all’arreda-mento e, decidendo sulla base di tale came-ra, come proseguire.Lo sviluppo a piccoli pezzi si concretò in mol-teplici modelli di produzione, quale quelloprototipale, quello incrementale, quello aspirale ecc.. In termini di linguaggi di pro-grammazione viene dato l’avvio, nel suocomplesso, all’epoca dei linguaggi orientatiagli oggetti.Nei linguaggi orientati agli oggetti il sistemada costruire è rappresentato come un insie-me di entità che interagiscono tra loro e che,interagendo, producono il risultato finale;pertanto, lo sviluppo si concentra nella iden-tificazione di tali entità e nella successivascrittura del codice relativo ad esse e alle lo-ro mutue relazioni. I più famosi tra i linguaggidi programmazione orientati agli oggetti so-no senza dubbio Smalltalk [16] e C++ [31], an-che se il primo tra tali linguaggi è molto pro-babilmente SIMULA [9].Non esistono solo linguaggi di programma-zione orientati agli oggetti. Ci sono anche lin-guaggi di analisi orientati agli oggetti, lin-guaggi di progetto orientati agli oggetti e co-sì via. A questo proposito, si vuole menziona-re l’Unified Modeling Language (UML) [29],ora particolarmente in voga.Si parla, pertanto, spesso di sviluppo orien-tato agli oggetti come una metodologia a sestante, in cui ci si concentra su analisi orien-tata agli oggetti, progetto orientato agli og-getti, codifica orientata agli oggetti ecc.In realtà, è importante distinguere tra stru-menti e fini: probabilmente è più adeguato

parlare di metodi che usano i vari tipi di lin-guaggi orientati agli oggetti e che, qualchevolta, per esempio nel caso del famoso Ra-

tional Unified Process (RUP) [22], usano solo

linguaggi orientati agli oggetti.Lo sviluppo delle telecomunicazioni, ivi com-preso il mondo del web, portò alla necessitàdi definire processi di sviluppo che tenesseroconto di questa realtà molto dinamica e dilinguaggi che supportassero gli associatiprocessi di sviluppo. È questo il periodo del-l’avvento delle metodologie agili di program-mazione, che danno supporto esplicito siaalla mutevolezza di requisiti che alla dinami-cità del sistema da sviluppare.Gli utenti considerano molto importante po-ter eseguire gli stessi, identici segmenti dicodice su piattaforme diverse, nonché tra-sferirli e combinarli dinamicamente, secon-do schemi di calcolo sia sequenziali che pa-ralleli, per produrre rapidamente nuovi si-

stemi di elaborazione, se così ancora si pos-sono chiamare.I modelli orientati agli oggetti fornirono unimportante punto di partenza in quanto per-misero l’identificazione di entità base di com-putazione. Ma occorse dare un maggior im-peto sia alla dinamicità dello sviluppo e dellafornitura al cliente, che all’interoperabilità trasistemi e con risorse disponibili in rete, qualiarchivi, liste di utenti, e banche dati in genere.Divennero allora popolari i cosiddetti lin-

guaggi per lo sviluppo dinamico, in quantosono in grado di sostenere lo sviluppo di si-stemi componibili dinamicamente e intero-perabili tra loro.Una parte di questi linguaggi era formata dasemplici evoluzioni di linguaggi di scripting,ovvero linguaggi interpretati, finalizzati a gui-dare il sistema in ciò che esso doveva fare.Si diffusero, però, anche linguaggi di pro-grammazione completi che ottenevano glistessi scopi, incorporando anche quei co-strutti che via via, nell’evoluzione dei lin-guaggi, si erano affermati come essenziali.I più famosi esempi di questi linguaggi so-no Java e C#.Questa è la situazione in cui ci si trova oggi.È importante sottolineare che in questa car-rellata si sono messi in relazione processi disviluppo software con specifiche istanze dilinguaggi di programmazione. Aver associa-

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

41

0

0

0

1

to un linguaggio a un processo non deveperò in alcun modo far pensare che quel lin-guaggio sia nato come una risposta al biso-gno definito dal processo. Anzi, molto spes-so il linguaggio in sé anticipa il processo cuifa riferimento. L’ALGOL, uno dei primi lin-guaggi strutturati, fu concepito alla fine de-gli anni ’50 [10]; SIMULA, l’archetipo dei lin-guaggi orientati agli oggetti, venne svilup-pato negli anni ’60 [9]; i primi i linguaggi perlo sviluppo dinamico sono degli anni ’70: ilConcurrent Pascal [19] e tutta la varietà dilinguaggi prototipali prodotti dal gruppo diHewitt [18].

3. LA PROGRAMMAZIONEDI ALTO LIVELLO

Vediamo ora il nesso tra processo di svilup-po e linguaggio ad esso associato, al fine didiscuterne il legame.Come precedentemente osservato, la pro-grammazione di alto livello fu motivata dalbisogno di avere programmi scritti in formali-smi comprensibili a un largo numero di svi-luppatori e non dipendenti da architetturespecifiche.Tre particolari categorie di sviluppatori ebbe-ro, in questo senso, un peso preponderante:❙ gli scienziati e i tecnici - fisici, astronomi,chimici, ingegneri ecc., - che usavano i lin-guaggi per sviluppare applicazioni legate al-le proprie attività di ricerca e sviluppo;❙ i matematici, che stavano definendo le teo-rie alla base dell’informatica e dell’intelligen-za artificiale;❙ i responsabili dei sistemi informativi azien-dali, che volevano automatizzare vari tipi ditransazioni economiche e finanziarie sia perragioni di efficienza che per evitare erroriumani.Di conseguenza, tre linguaggi acquisironoun’importanza tale che ancora oggi, nelle lo-ro successive reincarnazioni, continuano adessere usati: FORTRAN, LISP e COBOL.❑ FORTRAN

Gli scienziati avevano bisogno di un linguag-gio che permettesse la scrittura e la successi-va elaborazione di formule complesse. Nac-que così il FORTRAN [1, 2], che iniziò la proprialunga storia nel 1954. Così lunga da renderereale la profezia degli anni ’70: “Non si sa co-

me sarà il linguaggio di programmazione del-l’anno 2000, ma si chiamerà FORTRAN!2”.Il FORTRAN funzionò bene per le applicazionidi calcolo scientifico e, di conseguenza, ebbeun notevolissimo successo in questo domi-nio, come evidenziato dalla profezia prece-dentemente citata.❑ LISP

Il LISP fu ideato da John McCarthy nel 1958con lo scopo di riportare in forma di linguag-gio di programmazione il modello computa-zionale del λ-calcolo.Il λ-calcolo fu definito dai padri dell’informa-tica, tra cui Church [8], e si diffuse presto, di-ventando uno dei modelli computazionaliprevalenti. Avere un linguaggio di program-mazione basato integralmente su di esso ri-vestiva, pertanto, un’importanza unica pergli scienziati di allora, che pensavano, così, dirisolvere gran parte dei loro problemi di svi-luppo software tramite la trascrizione, quasipedestre, di modelli in programmi.Per esperti di λ-calcolo l’uso del LISP fu, ed ètuttora, particolarmente indolore. Questa èuna delle fortune maggiori di tale linguaggio,ancora oggi, dopo quasi 50 anni dalla suaprima concezione, particolarmente popolarenel settore dell’intelligenza artificiale.❑ COBOL

Il linguaggio COBOL, originato all’inizio deglianni ’60 [25], ambiva a trasporre in linguag-gio di programmazione le transazioni econo-miche e finanziarie. Il punto di riferimento diquesto linguaggio erano gli operatori delmondo degli affari che avevano esperienza dibilanci, scritture contabili, tabulati, regoleprecise e spesso un poco ridondanti.Già la procedura seguita per la specifica dellinguaggio evidenziava questa origine. Essofu definito da un comitato formato dai leader

statunitensi dell’epoca. Tra gli altri, si ricor-da, per quanto concerne il settore privato, lapartecipazione di Burroughs Corporation,IBM, Honeywell, RCA, Sperry Rand e Sylva-nia Electric Products. Anche tre enti pubbliciparticolarmente rilevanti presero parte ai la-vori: US Air Force, David Taylor Model Basine il National Bureau of Standards.

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

0

0

0

1

42

2 Questa profezia è stata attribuita a vari studiositra cui J. Backus, S. Cray e D. McCracken.

Il comitato si suddivise in tre sottocomitati: ilprimo per la pianificazione a breve termine, ilsecondo per quella a medio termine, e il ter-zo per il lungo termine; quest’ultimo in realtànon incominciò mai a lavorare.È chiaro che, con queste premesse il lin-guaggio che sarebbe risultato, sarebbe sta-to preciso, ma anche un po’ ampolloso epesante da gestire. Questo fu, in effetti, edè tuttora, il COBOL.Tirando le somme, non c’è dubbio che an-che il COBOL assolva molto bene i propricompiti di chiarire le azioni che l’elaborato-re svolge in un linguaggio comprensibile daipropri utenti principali, ovvero da personeche si occupano di amministrazione, conta-bilità e finanza.

4. LA PROGRAMMAZIONESTRUTTURATA E DI SISTEMA

Come prima menzionato, la diffusione deglistrumenti informatici nonché l’ingrandirsi deisistemi da sviluppare, impose la definizionedi un processo di sviluppo.L’idea che parve più ovvia fu quella di basar-si su modelli modulari, concentrati sulla sud-divisione del lavoro in parti e la successivaspecializzazione dei compiti. Il modello disviluppo di riferimento fu chiamato waterfall,ovvero, a cascata proprio da questo.Si assistette, allora, a una particolare focaliz-zazione sullo sviluppo di linguaggi che per-misero la decomposizione flessibile del si-stema in sottosistemi.Come si è detto, anche il COBOL permettevauna suddivisione; tale suddivisione, però,era rigidamente predefinita dal linguaggio: ledivisioni erano “quelle tre”.Si desiderava, invece, poter dividere in modoche i moduli fossero definibili in modo chiaroe univoco dallo sviluppatore, che doveva an-che stabilire come un modulo interagisse congli altri moduli.Come già menzionato, il punto di partenzaper questo approccio fu l’ALGOL [10], seguitopoi dal C [21] e dal Pascal [20]. È, però, con ilModula 2 [35] e con l’Ada [15] che la program-mazione strutturata acquisisce la sua com-pleta espressione. Nel seguito, di questa se-zione si analizzano il Modula 2 e l’Ada. Si pre-senta, poi, una breve riflessione sulla nuove

versioni del FORTRAN, il FORTRAN 77 [12] e ilFORTRAN 90 [13].

4.1. Modula 2L’intento del Modula 2 è duplice:❙ da un lato, vuole favorire la suddivisione dellavoro in moduli indipendenti e comunicantisolamente tramite chiare interfacce;❙ d’altro lato, vuole semplificare la scrittura delmodulo nel suo complesso, separando la par-te dichiarativa, in cui si specifica quello che unmodulo fa, dalla parte implementativa, in cuisi implementano funzioni finalizzate a ottene-re quanto precedentemente dichiarato.In questo senso, il Modula 2 sembrò essere ilpasso fondamentale per risolvere i problemidella crisi del software tramite l’applicazionedei modelli fordisti.L’organizzazione in moduli garantiva la par-cellizzazione del lavoro, assicurando la pos-sibilità di scrivere sistemi sempre più gros-si. La separazione dell’interfaccia dall’im-plementazione assicurava sia la specializza-zione delle competenze (l’implementazioneera fatta da esperti dei diversi domini appli-cativi, ma l’uso era aperto a chiunque po-tesse leggere le specifiche descritte nell’in-terfaccia), sia che eventuali modifiche im-plementative operate a un modulo, dovute,per esempio, alla già allora veloce evoluzio-ne degli strumenti informatici, non provo-cassero effetti catastrofici per altri moduliche lo usavano.Il successo di Modula 2 non è tanto testimo-niato dalla diffusione del linguaggio, che ri-mase piuttosto limitata, quanto all’influen-za che ebbe su linguaggi sia esistenti che dinuova concezione. Modula 2 provò, infatti,che le idee dei modelli “a cascata” poteva-no avere riflessi essenziali sui linguaggi diprogrammazione. Sia C che FORTRAN si ag-giornarono per acquisire il maggior numeropossibile di caratteristiche di Modula 2 co-me una migliore separazione tra interfacciae implementazione, la tipizzazione strettaecc. Ada ricalcò tutta la struttura a modulinei propri package.

4.2. AdaAda nacque sotto l’egida del Dipartimentodella Difesa statunitense con l’ambizione divoler diventare il linguaggio universale per i

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

43

0

0

0

1

sistemi embedded, in primis, e poi per tuttal’informatica.Con tale sponsorizzazione, il successo sem-brava garantito. Il linguaggio rassomigliavamolto a Modula 2, a parte la nomenclatura: ilmodulo si chiamava package.Una peculiarità di Ada che vale la pena rimar-care è la presenza di una ricca scelta di mo-dalità di “passaggio parametri”: per valore,per risultato, per valore-risultato e poi, conuna forzatura, per riferimento via puntatori.Si può intravedere in questo il desiderio diformalizzare, non solo al livello alto del mo-dulo ma anche al livello più basso delle sin-gole funzioni, i protocolli di interazioni tra lediverse parti di programma.In ogni caso, essendoci poco da aggiungerea Modula 2, in chiave di chiarezza operativagli ideatori di Ada si concentrarono sull’e-stensione del linguaggio per gestire ambitidi programmazione utili in sistemi embed-

ded ma non considerati esplicitamente daModula 2, come la programmazione concor-rente e la gestione delle eccezioni, sull’am-pliamento dei tipi astratti tramite l’uso deigenerici e, infine, sulla definizione di unasemantica precisa.Queste estensioni, però, resero difficile ladefinizione formale dello stesso linguaggioe causarono dei ritardi evidenti nello svi-luppo di compilatori che ne permettesseroil largo utilizzo e la diffusione. Fu, pertanto,solo alla fine degli anni ’80 che Ada comin-ciò a prendere piede su larga scala, quandoormai i modelli “a cascata” si avviavano altramonto.

5. MODELLI A V

All’inizio degli anni ’80 il modello di sviluppo“a cascata” cominciò a evidenziare i propri li-miti, soprattutto per quanto concerne l’inca-pacità di gestire la variabilità dei requisiti.Come precedentemente menzionato, la solu-zione fu quella di “cercare di essere più preci-si” nello sviluppo del software, attribuendoalla scarsa precisione degli analisti, dei pro-gettisti e degli implementatori, il mancatosuccesso del linguaggio.Si passò allora al modello di sviluppo “a V”,in cui si associava a ogni fase di sviluppo(ovvero analisi, progetto e codifica), una

batteria di test per verificare la sua corret-tezza. I test andavano eseguiti quando labatteria di test sottostante era stata com-pletata. In pratica, il flusso delle attivitàera: analisi, progetto, codifica e poi testdella codifica, test del progetto, test dell’a-nalisi. Dato il movimento discendente (dalgenerale al particolare) nella fase di svilup-po e ascendente (dal particolare al genera-le) nella fase di test, si chiamò questo mo-dello “a V”.Nello sviluppo del codice si ebbe un riflessodiretto del modello a V tramite le cosiddette“asserzioni”.In pratica, si definivano per ogni funzionepre-condizioni e post-condizioni che doveva-no essere soddisfatte prima e dopo l’esecu-zione di ogni funzione. Inoltre, si potevanoinserire delle espressioni booleane in punticritici di una funzione, le asserzioni, che do-vevano essere sempre valutate vere. Il pro-blema passava allora alle definizioni di que-ste condizioni e asserzioni e alla loro valuta-zione durante l’esecuzione del programma[4]. Di fatto, nessuna versione di un linguag-gio di programmazione effettivamente usatoinglobò l’idea delle asserzioni, a parte le li-brerie di asserzioni del compilatore gnu delC. Essa rimase, quindi, nell’aria e ora si è pra-ticamente tradotta nel concetto di test first,tanto caro agli sviluppatori utilizzanti le me-todologie agili.

5.1. FORTRAN 77 e FORTRAN 90L’evoluzione del FORTRAN verso la program-mazione strutturata e di sistema avvenne indue passi: il FORTRAN 77 e il FORTRAN 90.Il FORTRAN 77 venne definito con l’intento dieliminare gli aspetti chiaramente obsoletidelle versioni di FORTRAN ancora largamentein uso nei primi anni ’80: il FORTRAN 4 e ilFORTRAN 66.In particolare, venne definito un costruttoper i cicli e si obbligò il programmatore a de-finire esplicitamente tutte le variabili, in mo-do da limitare le possibili sviste.Le novità portate dal FORTRAN 90 furonomolteplici: eliminò i vincoli di formattazioneprecedentemente descritti, permise la defi-nizione di tipi strutturati e di moduli, aggiun-se un insieme di costrutti di controllo equi-valenti a quelli di Modula 2 e di Ada, tra cui

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

0

0

0

1

44

le tecniche di passaggio parametro tipichedi Ada, e incluse anche alcune tecniche pri-mordiali per la definizioni di oggetti. Inoltre,aggiunse strumenti per la programmazioneparallela, dato che gli sviluppatori in FOR-TRAN erano spesso scienziati interessati acalcoli su strutture di grandi dimensioni.

6. LA PROGRAMMAZIONEORIENTATA AGLI OGGETTI

Verso la metà degli anni ’80, l’informatica com-prese che i problemi dei modelli di sviluppo acascata nascevano dall’intrinseca incertezzache pervade il modo stesso di svilupparesoftware.Questo cambiava radicalmente la possibilesoluzione. Occorreva un modello, non tantofocalizzato a raggiungere una chimericaesattezza, quanto capace di gestire una con-genita variabilità.I modelli di divisione del lavoro diventavano,di colpo, inadeguati: se lo scopo di un siste-ma da sviluppare non era chiaro, una qualun-que sua suddivisione rischiava di rendere an-cora meno chiaro lo scopo del sistema.Si pensò allora a uno sviluppo a piccoli pezzi.L’idea fu di prendere come punto di partenzal’ambito applicativo dei sistemi da svilupparee di studiare a fondo tale ambito con lo scopodi capire quali elementi andavano sicuramen-te considerati nel sistema da sviluppare. Peresempio, se si trattava di sviluppare un siste-ma per la gestione di un aeroporto, occorrevaconsiderare l’aspetto dei voli, dei passeggeri,dei biglietti e così via. Si poteva allora partirenello sviluppo dal modello di comportamen-to di tali entità.Tali entità furono chiamate oggetti e, conti-nuando la metafora, trasmissioni di mes-

saggi tra diversi oggetti si sostituirono achiamate a funzioni. Ogni oggetto avevauna serie di metodi per la risposta ai mes-saggi che rimpiazzarono il corpo delle fun-

zioni3.L’uso degli oggetti facilitò anche le comuni-cazioni con il cliente, in quanto gli oggettierano presi dal linguaggio del dominio appli-

cativo noto al cliente stesso e, quindi, il flus-so della computazione diventava spesso dipiù semplice comprensione.Lo sviluppo a piccoli pezzi si concretizzò in di-versi modelli di produzione, tra cui si ricorda-no i modelli incrementali, quelli prototipali equelli a spirali. Tutti facevano esplicito riferi-mento alla programmazione orientata aglioggetti.

6.1. C++

Infatti, tra gli scopi del C++ ci fu quello di ren-dere facile la transizione alla programmazio-ne orientata agli oggetti per la comunità de-gli sviluppatori di sistema in ambiente Unix,solita a programmare in C.Il C++ è un linguaggio in questo senso contro-verso: i puristi lo considerarono, fin dall’ini-zio, non un vero linguaggio orientato agli og-getti, ma un ibrido e gli preferirono sistemipiù integri, quali Smalltalk.In questo articolo, non si vuole entrare neldibattito su quale sia il migliore linguaggioorientato agli oggetti. Di fatto, però, C++ è ilpiù diffuso e, quindi, rappresenta un puntodi riferimento importante se si vuole studia-re l’evoluzione dei linguaggi di programma-zione.In primis, si ha la presenza del codice del-l’implementazione insieme a quello della di-chiarazione, seppure con una separazionetra zona pubblica – accessibile a tutti, e zo-

na privata – accessibile solo agli implemen-tatori. Questo sembra contraddire l’ideadella divisione e della specializzazione dellavoro. Ma se la dimensione del codice rima-ne contenuta, secondo l’idea dello sviluppoincrementale, essa serve a fornire una spe-cifica operazionale al metodo. Chiaramente,se il codice è lungo e complesso, la sua pre-senza è dannosa.L’idea di documentare il codice con il codicestesso ebbe molta fortuna e ora è largamen-te usata in Java, anche tramite una specificastrutturazione dei commenti, con un parti-colare strumento chiamato JavaDoc, cheanalizza il codice ed estrae parti di com-menti formattati secondo una semplice echiara sintassi per fornire in modo automa-tico una documentazione sintetica ma effi-cace del sistema.Le definizioni di zona pubblica e zona privata

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

45

0

0

0

1

3 Peraltro, i metodi sono anche chiamati funzioni

membro.

diventano, pertanto, quasi un suggerimentoall’utente della classe su dove concentrare,in modo prioritario, la propria attenzione,piuttosto che una separazione contrattualedi compiti4.

6.2. FORTRAN 95 e FORTRAN 2000 e altrilinguaggiIl FORTRAN proseguì la propria evoluzioneverso l’universo della programmazione a og-getti con due versioni: il FORTRAN 95 e ilFORTRAN 2000. Esse vengono qui nel segui-to brevemente tratteggiate.❙ Il FORTRAN 95 arricchì il linguaggio conuna serie di costrutti di controllo più raffina-ti e con ulteriori specializzazioni del concet-to di funzione: le funzioni pure e le funzionidi elementi. Le funzioni pure non hanno ef-fetti collaterali, non agiscono cioè su varia-bili globali o di ambiente. Le funzioni di ele-menti hanno come argomenti e restituisco-no solo valori scalari. Si definirono, inoltre,tecniche per una gestione più pulita deipuntatori, inclusa la loro inizializzazione el’allocazione e deallocazione dinamica dellamemoria. Infine, si rese più robusta la ge-stione dei tipi derivati.❙ Il FORTRAN 2000 è attualmente in corso didefinizione e sta compiendo un passo so-stanziale nel rendere FORTRAN completa-mente orientato agli oggetti [28]. In partico-lare, si sta rafforzando la gestione dei generi-ci estendendoli ai tipi derivati, l’uso dei pun-tatori a funzione e la gestione di oggetti poli-morfi. Inoltre, sta migliorando l’interfaccia-mento con altri linguaggi orientati agli ogget-ti e non, per rendere più agevole l’interopera-bilità tra sistemi, secondo i cardini dello svi-luppo a piccoli pezzi.L’approccio generale è più ridondante delC++. In particolare, c’è una marcata separa-zione tra interfaccia e implementazione chericorda i linguaggi strutturati; questa inter-faccia addirittura disaccoppia il nome delmetodo dal corpo del metodo, richiedendola presenza di un esplicito operatore per laconnessione: l’operatore ⇒ . La filosofia ge-

nerale, però, è chiaramente quella ibrida aoggetti del C++.

7. LA PROGRAMMAZIONEDI SISTEMI COMPONIBILIDINAMICAMENTE

La programmazione orientata agli oggetticausò un miglioramento sostanziale dellosviluppo del codice. Di contro, però, richieseuna competenza decisamente superiore daparte degli sviluppatori.Si potrebbe quasi asserire che mentre i mo-delli a cascata volevano risolvere i problemicon la formalizzazione delle attività da svol-gere e la specializzazione del lavoro, i mo-delli a piccoli pezzi si concentravano sulladefinizione di un linguaggio ricco che per-mettesse di catturare nel modo più comple-to possibile i requisiti dei clienti, comunqueorganizzati in insiemi di dimensioni ridotte.

7.1. Limiti dell’approccio orientatoagli oggettiDue fattori tra loro connessi emersero,però, con effetti dirompenti. Il primo fu checi si rese conto che l’uso del C++ o di un altrolinguaggio di simili connotazioni richiedevaun’adeguata formazione e che la formazio-ne del personale in un linguaggio comples-so era ovviamente non semplice, soprattut-to se tale personale proveniva da anni diuso di linguaggi di programmazione menoevoluti.Il secondo fattore fu la domanda del mercatodi prodotti in tempi brevi e il contestualecomparire sulla scena del web, che rendevaancora più impellente tale domanda e ag-giungeva la necessità di avere un linguaggioche si adattasse a combinare pezzi di codiceche si muovessero sulla rete.La combinazione di questi due fattori contri-buì alla fortuna del linguaggio Java.Le metodologie agili, poi, definirono un pro-cesso di sviluppo che sosteneva gli stessiobiettivi: limitare la complessità di sviluppo,favorire la consegna del prodotto all’utentein tempi brevi e certi anche se con funziona-lità ridotte, garantire la qualità e eliminare glisprechi dovuti a sviluppi di moduli inutili o adattività sì connesse con lo sviluppo ma nondirettamente produttive.

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

0

0

0

1

46

4 Si noti che in Smalltalk, il linguaggio di program-mazione agli oggetti considerato forse più puro,questa suddivisione non esiste.

7.2. JavaNacque con l’intento di definire un linguag-gio ad oggetti quanto più completo e puro

possibile, utilizzando come base la sintassidel C e senza compiere gli errori dell’Objecti-ve C [5], un precedente linguaggio nato con imedesimi scopi ma naufragato per l’ambi-guità di fondo di non avere né la pulizia di unlinguaggio ad oggetti né la flessibilità del C.Per semplificare l’apprendimento e la gestio-ne dei programmi scritti nel linguaggio, e ri-durre, quindi, lo sforzo per l’apprendimentodi costrutti inutili, si eliminarono alcune ca-ratteristiche particolarmente onerose delC++: la gestione della memoria dinamica la-sciata all’utente, i generici, l’ereditarietàmultipla delle classi e il passaggio parametriper riferimento.Per facilitare l’uso del sistema in modo dina-mico sulla rete si cambiò il meccanismo digenerazione dell’oggetto e dell’eseguibile, siresero tutte le funzioni virtuali (con binding

ritardato) e si definirono costrutti specificiper la gestione della concorrenza.Dall’analisi del processo di compilazione edesecuzione (Figura 2) si può capire l’aderen-za delle specifiche del linguaggio agli scopidi Java precedentemente delineati e ai mo-delli di sviluppo agili.

Nel caso del C++, come nel caso dei linguaggidi alto livello5 e dei linguaggi strutturati finoraconsiderati, fu scelto il seguente processo perla generazione di un programma eseguibile:❙ dapprima un modulo, chiamato “compila-tore”, provvede ad analizzare il file sorgente

e a generare un file “oggetto”, o “OBJ”, cheè indipendente dal linguaggio sorgente ori-ginario, ma dipendente dall’hardware e dalsistema operativo;❙ quindi, un secondo modulo, chiamatolinker, dipendente dallo specifico hardwaree sistema operativo, ma spesso indipen-dente dal linguaggio sorgente, si occupa dicercare e unire i diversi moduli oggetto, siaquelli sviluppati dal singolo programmatoreche quelli provenienti dal sistema operati-vo, per costruire il modulo eseguibile, quel-lo che può essere caricato e fatto funzionaresul calcolatore da solo e in un unico blocco.In alcuni testi e in alcuni ambienti di sviluppole due fasi sono trattate in modo così conse-quenziale da essere chiamate genericamen-te entrambe compilazione.Va da sé che in questo contesto non è assolu-tamente scontato che un modulo oggetto oun modulo eseguibile sviluppati per una da-ta configurazione di hardware e sistema ope-rativo funzionino su un’altra configurazione.

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

47

0

0

0

1

5 In realtà, il LISP ha un processo di interpretazione più simile a quello di Java che agli altri. Di fatto, però, ilprogrammatore medio del LISP di solito non percepisce questa differenza, e quindi non sfrutta le poten-zialità ad essa collegate.

FIGURA 2Analisi del processodi compilazione edesecuzione in Javae in C++

Src Javaper classe

1

Compilatore -compila in bytecode (BC) Compilatore -compila in modulo OBJ

Java Virtuale Machine -carica il BC unaclasse alla volta e lo esegue sull’HW

Linker -identifica i moduli OBJ necessarie, con essi, crea un modulo eseguibile

Src C++

per file 1Src C++

per file 2Src C++

per file k

OBJ C++

per file 1OBJ C++

per file 2OBJ C++

per file k

Src Javaper classe

2

Src Javaper classe

k

BC Javaper classe

1

BC Javaper classe

2

BC Javaper classe

k

ComputerHW 1

ComputerHW 2

ComputerHW n

ComputerHW m

Modulo eseguibile del progetto(file 1 .. k) per il computer m

Java C++

È di conseguenza esclusa la possibilità che lostesso codice eseguibile possa migrare dimacchina in macchina continuando a funzio-nare senza nulla toccare.Inoltre, occorre che tutto il sistema sia co-struito in un solo colpo e che, al momento dellink, si abbia a disposizione la versione finaledi tutti i moduli oggetto necessari; tale ver-sione non è più cambiabile6.In Java, fu preferito un approccio completa-mente differente.Il codice è compilato, una classe alla volta, daun compilatore Java che lo trasforma in unmodulo simil-oggetto chiamato di solito “by-tecode”. Per ogni classe pubblica (ovvero,ogni classe utilizzabile al di fuori del packagedi definizione) esiste uno e un solo file byteco-de. Il bytecode è lo stesso per ogni compilato-re Java, indipendentemente dalla configura-zione di sistema operativo e hardware in uso.Un altro modulo chiamato virtual machine omacchina virtuale7 provvede, quindi, a cari-care ed eseguire una ad una le classi effet-tuando la ricerca del bytecode delle classinecessarie dinamicamente nel corso dell’e-secuzione del programma stesso.La macchina virtuale disaccoppia il bytecodedal sistema operativo e dall’hardware sotto-stante, fornendo tutti quegli strumenti ne-cessari per l’esecuzione del programma e oc-cupandosi anche della gestione automaticadella memoria dinamica e della concorrenza.Il funzionamento delle macchine virtuali è, inpratica, lo stesso8 per ogni sistema operativoe per ogni hardware, anche se, ovviamente, ilcodice eseguibile della macchina virtualenon è necessariamente lo stesso.Ne risulta che il programma può tranquilla-mente migrare da un computer all’altro, pur-ché ovviamente il calcolatore sia dotato dellamacchina virtuale adeguata allo scopo.Il caricamento in memoria fatto per classipermette, inoltre, di limitare la quantità di co-

dice da trasmettere sulla rete, in quanto sipossono utilizzare le parti di classi di sistemapresenti sul calcolatore destinazione. Inoltre,il caricamento parziale di codice permette direndere maggiormente dinamici lo sviluppoe la successiva evoluzione del sistema.Se si definiscono in modo chiaro le dipenden-ze mutue tra classi, cosa difficile ma non im-possibile, soprattutto se si mantengono gliassunti della programmazione orientata aglioggetti, di rendere gli oggetti costantementeriferiti alle entità del dominio applicativo, èallora possibile che gli oggetti di versioni di-verse della stessa classe rispondano aglistessi messaggi con risposte sicuramentenon identiche, ma equipollenti dal punto divista dello sviluppo del sistema, in modo cheil sistema possa evolvere dinamicamente.Un uso tipico di questo approccio dinamicosia per quanto concerne la migrazione delcodice che la definizione di versioni multi-ple della stessa entità, si ha nella possibi-lità di caricare nelle pagine web frammentidi codice Java chiamati applet che vengonotrasmessi dal server web al calcolatore chesta visualizzando la pagina web e vengonopoi eseguiti sulla macchina virtuale resi-dente sul calcolatore destinazione.Java riconobbe l’importanza di usare la sin-tassi di un linguaggio affermato, il C++, inmodo da invogliare i programmatori in talelinguaggio a considerarlo come una poten-ziale alternativa.

7.2. Autodocumentazione e test-firstin JavaPer completare la panoramica su Java e ap-profondire il legame che lo lega con i model-li di sviluppo agile, è importante menziona-re che Java fu concepito anche per fornire unsupporto all’autodocumentazione del codi-ce. Insieme al linguaggio fu costruito untool per documentare la struttura in classi

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

0

0

0

1

48

6 Si semplifica la realtà ignorando, volutamente, le librerie di sistema caricabili dinamicamente o quelle con-divise: esse non sono state pensate per cambiare il comportamento a run time di un sistema quanto perpoter ridurre le dimensioni dell’eseguibile e rendere più veloce il suo caricamento ed esecuzione, ovvero(come nel caso delle DLL sui vecchi sistemi operativi DOS) per renderlo eseguibile in toto.

7 Spesso si usa anche in italiano il termine inglese.8 Si trascurano i problemi legati alle diverse versioni di macchina virtuale, poiché si tratta di un problema di

gestione delle configurazioni e non di struttura del linguaggio di programmazione.

anche tramite l’identificazione e l’estrazio-ne di commenti particolari che il program-matore può scrivere all’uopo.I cultori delle metodologie agili estesero su-bito a Java l’approccio test-first, originaria-mente pensato per Smalltalk.Test-first è un processo di scrittura del codi-ce in cui dapprima si definisce per ogni me-todo di una classe, non appena si sa di do-verlo sviluppare e si conoscono i suoi para-metri, uno o più test che ne verifichino ilcorretto comportamento e, quindi, si usanoi test come guida per lo sviluppo della clas-se. La similitudine tra l’approccio test-firste le asserzioni precedentemente citate èevidente.Test-first è particolarmente efficace in Javanello sviluppo di sistemi componibili dinami-camente, in quanto le moltitudini di test chevengono così via via create diventano un con-trollo molto efficiente contro possibili disalli-neamenti che si vengono a creare quando sicostruisce il codice a pezzetti e a intervallisuccessivi, magari anche in luoghi distribuitigeograficamente.L’approccio test-first fu consolidato in Javacon jUnit, il porting di sUnit, lo strumentoprecedentemente usato in Smalltalk per po-ter eseguire automaticamente tutti i test inun colpo solo. In un contesto di sviluppoagile, jUnit rappresentò un passo essenzia-le per assicurarsi che i test fossero effettiva-mente sviluppati prima del codice e costan-temente eseguiti.In ultima analisi, si può dire che l’autodocu-mentazione e il test-first rappresentino un’ul-teriore forte evidenza che lega processo disviluppo agile ai linguaggi per i sistemi com-ponibili dinamicamente.A questo punto si potrebbe obiettare cheSmalltalk fu proprio il precursore dei linguag-gi per sistemi componibili dinamicamente enon tanto dei linguaggi a oggetti. Questaobiezione è, infatti, molto interessante: deli-nea, in modo significativo, l’importanza di ta-le linguaggio ed evidenzia l’ispirazione di chilo pensò. Del resto, Smalltalk è legato ancheal filone del LISP e dei linguaggi funzionali[30] e, come già menzionato, ci sono legaminon ovvi ma profondi tra i modelli funzionaliproposti dal LISP e i linguaggi per sistemicomponibili dinamicamente.

8. LINGUAGGI, LINGUAGGI,LINGUAGGI, …

In questa veloce carrellata sono stati eviden-ziati solo una minima parte dei linguaggi diprogrammazione usati.In particolare, non è stata spesa neancheuna parola sulla serie dei linguaggi Micro-soft a partire dai primi BASIC adattati per ilDOS fino a C# ecc.. Questo non vuole esserein alcun modo una censura nei confrontidella più grande azienda software del mon-do, che molti criticano ma che indubbia-mente ha finanziato ricerche di altissimaqualità che hanno contribuito alla crescitadel mondo dell’informatica.Bisogna riconoscere però che, quando haoperato direttamente e non tramite i finan-ziamenti alla ricerca erogati all’Università,Microsoft si è focalizzata nella direzione delperfezionamento di strutture linguistichegià esistenti e in quella degli ambienti disviluppo per rendere quanto più efficientepossibile alcune tecniche di sviluppo consi-derate strategiche, piuttosto che nella crea-zione di nuove strutture linguistiche di inte-resse per questo lavoro.Ci sono poi i linguaggi di script che hanno co-stituito la base della programmazione di si-stema. Anche in questo caso, l’averli ignoratinon significa averli sottovalutati. Il linguag-gio della C-shell ha formato generazioni di si-stemisti Unix, così come PERL successiva-mente ha permesso la creazione dei prototipidei siti web dinamici, e quindi PHP9 e così via.Bisogna però ripetere quanto detto per Mi-crosoft: sono linguaggi molto efficaci mache sublimano alcune caratteristiche esi-stenti in un dato linguaggio per un dominioapplicativo ben preciso: per esempio, laprogrammazione di pagine web, la creazio-ne di portali, la programmazione in the

small di sistema. Come tali, sono fuori dal-l’ottica di questo articolo.Una menzione va poi ai linguaggi funzionali,al di là del LISP, e a quelli logici. Per gli altri,

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

49

0

0

0

1

9 Il termine PHP è un acronimo ricorsivo che staper PHP Hypertext Processor, ovvero, processo-re PHP di ipertesti. Questo acronimo ben eviden-zia le caratteristiche di questo linguaggio, oggidiventato molto popolare.

anche se hanno creato strutture interessanti,non si può dire che si siano diffusi in modo si-gnificativo. Inoltre, e questa è una opinionemolto personale dell’autore, hanno più usa-to e modellato teoricamente caratteristichegià precedentemente pensate piuttosto chegestito un sistema nuovo: i tipi generici sononati prima di ML10 (Meta Language); le gerar-chie di classi sono nate molto prima di Ha-skell; l’analisi delle strutture “ad alberi” erapresente in YACC prima del PROLOG; la pro-grammazione a clausole era presente primadei recenti linguaggi a vincoli.Forse due aspetti sono originali a questi lin-guaggi: la valutazione lazy per la creazionedi strutture infinite –propria di alcuni lin-guaggi funzionali quali LML e Haskell, e lapossibilità di avere parametri che sono con-testualmente di input o di output, come nelcaso del PROLOG.Ma, dopo l’entusiasmo iniziale, non pare chequesti modelli abbiano originato sostanzialiavanzamenti nella disciplina.È opportuno sottolineare che questo nonvuol dire affatto che tali linguaggi si siano ri-velati inutili semplicemente, essi non si le-garono mai ad alcun processo in quel bino-mio indivisibile di cui si discute. Con unametafora si può affermare che nessuno pen-serebbe di andare con un’auto di Formula 1per i vicoli del centro storico di Genova, ocon una bicicletta in autostrada, ma questonon significa che le macchine di Formula 1 ole biciclette siano inutili.

9. SI PUÒ TRARREUNA CONCLUSIONE?

Si pensa che l’analisi effettuata confermi l’i-potesi di partenza sulla imprescindibile con-nessione tra linguaggio e processo.È difficile ma interessante provare a predire ilfuturo dei linguaggi usando tale paradigma.Chiaramente non si possono che identificaretendenze passate e capire come queste ten-denze possano evolversi.Si può poi notare che i processi di produzio-ne del software e poi i linguaggi hanno attra-

versato un’interessante parabola in terminidi complessità (Figura 3).Come già precedentemente ricordato, dap-prima si cercò di rispondere ai bisogni dell’in-dustria software con modelli di produzionesempre più complessi e in secondo momen-to, dato che i processi diventavano via viasempre più pesanti, i linguaggi li seguironoaccrescendo le proprie funzionalità.Finalmente, con i modelli incrementali, si ar-rivò a capire che rendere il processo ancorapiù complesso non avrebbe giovato: il siste-ma era diventato troppo complesso e occor-reva trovare qualche altro approccio e sem-plificare il modello di sviluppo per sperare inulteriori miglioramenti.I linguaggi continuarono a crescere, in com-plessità, fino al proverbiale C++. Una diverten-te falsa intervista, con Stroustrup11, l’inven-tore del C++, evidenzia come la comunità de-gli sviluppatori abbia percepito la comples-sità di questo linguaggio.Alla fine, ci si rese conto che la complessitàdel linguaggio non era più sostenibile: sem-plicemente costava troppo formare sviluppa-tori per tali linguaggi o mantenere sistemiscritti in tali linguaggi. Con Java, iniziò la pa-rabola discendente di complessità.Quanto durerà la discesa? Chi scrive pensache continuerà ancora. La diffusione deiprocessi agili è irreversibile in tutti i settoridel mondo produttivo ed essa è solo agli ini-zi nell’industria informatica. Essa porta il bi-sogno di eliminare lo spreco nella program-mazione.L’eliminazione delle attività inutili è, quindi,un cardine delle future tendenze. Essa potràrealizzarsi come semplificazione dei linguag-gi di programmazione, ovvero come l’uso diquei linguaggi che hanno sintassi ridotte alminimo, come Smalltalk.Essa potrà anche apparire sottoforma dinuovi sistemi integrati per lo sviluppo, cheautomatizzino o semiautomatizzino le atti-vità e i controlli del programmatore. Si pensi,per esempio, all’efficacia di JUnit in Java peril test e di Javadoc per la documentazione.Si può, quindi, fare una semplice considera-

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

0

0

0

1

50

10 ML fu il primo linguaggio funzionale ad avere una diffusione oltre la ristretta cerchia degli inventori.11 URL: http://www.nsbasic.com/newton/info/nsbasic/interview.shtml

zione, quasi scherzosa. Sicuramente, chiun-que profetizzò le fortune del FORTRAN12, omeglio, del suo nome e della struttura dellasua sintassi, ebbe ragione. Questo è il mon-do del FORTRAN e non si sarebbe affatto stu-piti di trovarsi un FORTRAN 3000 “tra i piedi”tra qualche anno…Di fatto, la storia dell’uso dei linguaggi diprogrammazione condiziona quelli che sa-ranno i linguaggi in uso nel futuro. Gli eco-nomisti chiamano questo fenomeno path

dependency [23].Un esempio classico è il layout della tastie-ra della macchina da scrivere e del compu-ter, la cui inefficienza è provata rispetto asoluzioni alternative, ma che risulta nonconveniente cambiare in quanto il costo ditransizione sarebbe maggiore del guadagnoottenuto cambiando.La fortuna della famiglia dei linguaggi basatisul primo FORTRAN o di quelli basati sul C staprobabilmente in questo. Potrebbero esiste-re altri sistemi radicalmente diversi e supe-riori per scrivere codice. Per esempio, l’auto-re pensa che Smalltalk sia estremamente piùsemplice e compatto. Di fatto, la transizione

a una sintassi diversa rende questo percorsodi difficile praticabilità, forse impossibile.Resta, dunque, sempre più attuale la strate-gia di cambiare il linguaggio piuttosto che

cambiare linguaggio. C++ e Java si stannomuovendo in questa direzione.

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

51

0

0

0

1

FIGURA 3Evoluzionedella complessitànel processoe nel linguaggio

12 Si fa riferimento alla citazione sulle fortune delnome FORTRAN, il cui autore, come detto in nota2, non è determinato con certezza.

Complessità

Complessitàdel processo

Linguaggiassemblativi

Sviluppo senzaregole particolari

Incrementale,Spirale, ...Waterfall, a “V”

Primo tentatividi “ordine”

nello sviluppo

Linguaggidi alto livello

Linguaggistrutturati

Linguaggi orientatiagli oggetti

Linguaggi per losviluppo dinamico

Complessitàdel linguaggio

Modello

Metodologie agili

Nell’articolo si è parlato in svariati punti del concetto di “tipo di dato”.I tipi di dati rispondono a due scopi.Gli ingegneri del software hanno sempre nutrito il desiderio impossibiledi poter controllare in modo statico la correttezza semantica di un pro-gramma. Di fatto, le uniche verifiche fattibili sono quelle sintattiche. Inquesto contesto si è cercato di raffinare sempre più ciò che è sintattica-mente esprimibile, al fine di massimizzare quanto sia controllabile primadell’esecuzione di un programma.Il primo scopo dei “tipi di dato” è proprio quello di aumentare le particontrollabili tramite la definizione di vincoli sulla operazioni fattibili.Così come, ad esempio, in matematica per ogni tipo di numero (naturale,intero, razionale ecc.) esistono un insieme di operazioni ammissibili, undominio per tali operazioni e un co-dominio, con i tipi di dati si vuole for-nire all’utente la possibilità di definire tipi come quelli matematici e ope-razioni ammissibili, in modo tale che, laddove si compia una operazionenon ammissibile, un controllo sintattico possa tempestivamente infor-mare lo sviluppatore.I tipi di dati utilizzabili in un programma si sono evoluti da semplice com-binazioni di più valori elementari, come nel primo FORTRAN, a comples-se algebre di ordine superiore con relazioni funzionali e definizioni an-che ricorsive, come in C++.Anche nel caso dei tipi di dati, passando da C++ a Java si è assistito a unaprogressiva semplificazione dei tipi ammissibili.Il secondo scopo dei tipi è stato quello di fornire un supporto alla mo-dularità, tramite l’astrazione dei dati. Di questo si discute anche nellaparte finale dell’articolo.

Bibliografia

[1] Backus J.W.: Automatic Programming: Proper-

ties and Performances of FORTRAN Systems I

and II. Atti del Symposium of Mechanisation ofThought Processes, Teddington, UK, 1958.

[2] Backus J.W.: The History of FORTRAN I, II, andIII. In: IEEE Annals of the History of Computing,Vol. 20, n. 4, 1998, p. 68-78.

[3] Banham R., Newman P.: The Ford Century: Ford

Motor Company and the Innovations That Sha-

ped the World. Artisan Sales, 2002.

[4] Broy M., Krieg-Brückner B.: Derivation of InvariantAssertions During Program Development by Tran-sformation. Transactions on Programming Lan-

guages and Systems, Vol. 2, n. 3, 1980, p. 321-337.

[5] Budd T.: An Introduction to Object-Oriented

Programming. Addison Wesley, 1991.

[6] Cox B.: Object Oriented Programming – An Evo-

lutionary Approach. Addison Wesley, 1986.

[7] Chidamber S.R., Kemerer C.F.: A metrics suitefor object-oriented design. IEEE Transactions

on Software Engineering, Vol. 20, n. 6, June1994, p. 476-493.

[8] Church A.: The Calculi of Lambda-Conversion. Prin-ceton University Press, Princeton, New Jersey, 1941.

[9] Dahl O.-J., Nygaard K.: SIMULA –An Algol BasedSimulation Language. Communications of the

ACM, Vol. 9, n. 9, 1966, p. 671-678.

[10] Dijkstra E.W.: Primer of Algol 60 Programming.Academic Press, 1962.

[11] Dodrill G.: Coronado Enterprises Modula-2 Tutor.1987, URL: http://www.modula2.org/tutor/

[12] Ellis T., Miles R.: A Structured Approach to FOR-

TRAN 77 Programming. Addison-Wesley Publi-shing, 1983.

[13] Ellis T., Miles R.: FORTRAN 90 Programming.Addison-Wesley Publishing, 1994.

[14] Feuer A.R., Gehani N.H.: Comparison of the Pro-gramming Languages C and Pascal. ACM Com-

puting Surveys, January, 1982.

[15] Gehani N.H.: Unix Ada Programming. PrenticeHall, 1985.

[16] Goldberg A., Robson D.: Smalltalk-80: The

Language and Its Implementation. AddisonWesley, 1983.

[17] Graham P.: History of FORTRAN, URL:http://www.paulgraham.com/history.html

[18] Hewitt C., Bishop P., Steiger R.: A Universal Mo-

dular Actor Formalism. Atti della 3rd Internatio-nal Joint Conference on Artificial Intelligence,Stanford, CA, 1973.

[19] Hansen P.B.: The Programming Language Con-current Pascal. IEEE Transactions on Software

Engineering, Vol. 1, n. 2, 1975, p; 199-207.

[20] Jensen K., Wirth N.: PASCAL User Manual and

Report. Springer, 1975.

[21] Kernighan B.W., Ritchie D: The C Programming

Language. Prentice Hall, 1978.

[22] Kruchten P.: The Rational Unified Process: An

Introduction. Addison Wesley, 1998.

[23] Liebowitz S.J., StMargolis S.E.: Path Dependence,Lock-in, and History. Journal of Law, Economics,

and Organization; 1995, anche disponibile on-li-ne all’URL: http://wwwpub.utdallas.edu/~lie-bowit/paths.html

[24] McCarthy J.: A Revised Version of MAPLIST. MIT AILab., AI Memo n. 2, Cambridge, September 1958.

[25] McCracken D.D.: A Guide to Cobol Program-

ming. Wiley, 1963.

[26] Meyer B.: Eiffel: The Language. Prentice Hall,1992.

[27] Murtagh J.L., Hamilton J.A.: A comparison ofAda and Pascal in an introductory computerscience course. ACM SIGAda Ada Letters, Vol.18, n. 6, 1998.

[28] Reid J.: The New Features of Fortran 2000. URL:www.ukhec.ac.uk/publications/reports/N1507.pdf

[29] Rumbaugh J., Jacobson I., Booch G.: The UML

Reference Manual. Addison Wesley, 1998.

[30] Sethi R.: Programming Languages: Concepts

and Constructs. Addison Wesley, 1996.

[31] Stroustrup B.: The C++ Programming Language.Addison Wesley, 1996.

[32] Tsaptsinos D., Davies R., Rea A.: Fortran 90 – An

introduction to the language for beginners. URL:http://www.pcc.qub.ac.uk/tec/courses/f90/ohp/header_ohMIF_1.html

[33] US Department of Defence: Department of De-

fense Requirements for High Order Computer

Programming Languages: Steelman. 1978.

[34] Wheeler D.A.: Ada, C, C++, and Java vs. The

Steelman. Ada Letters, July/August, 1997.

[35] Wirth N.: Programming in Modula-2. SpringerVerlag, 1982.

GIANCARLO SUCCI è ordinario di Informatica e direttoredel Center for Applied Software Engineering pressola Libera Università di Bolzano, dove si occupa di me-todologie agili per lo sviluppo software, metrichesoftware, ingegneria del software empirica, stru-menti di e-learning nell’industria software, linee diprodotto software. È stato ricercatore presso l’Uni-versità di Trento, professore associato alla Universityof Calgary e quindi professore ordinario alla Univer-sity of Alberta, dove ha co-diretto l’Alberta SoftwareEngineering Research Consortium. È autore di più di150 articoli scientifici e di 5 libri.e-mail: [email protected]

M O N D O D I G I T A L E • n . 4 - d i c e m b r e 2 0 0 3

1

0

0

0

1

52