Dr. Carlo Pescio Intervista a Niklaus Wirth |
Pubblicato su Computer Programming No. 58
Non dovrebbe essere necessario presentare Niklaus
Wirth ai nostri lettori. Professore di informatica all'ETH di
Zurigo, Wirth ha progettato il Pascal, Modula 2 ed Oberon, e nei
primi anni settanta è stato uno dei fautori del metodo
di sviluppo per raffinamenti successivi. Ha scritto diversi libri
di grande importanza, tra cui vanno ricordati "Algoritmi
+ Strutture Dati = Programmi" e "Principi di Programmazione
Strutturata", e molti articoli che hanno contribuito in modo
significativo allo sviluppo della programmazione. Per la sua influenza
sul mondo del software, nel 1984 Wirth è stato insignito
di una delle più alte onorificenze nel campo dell'informatica
(il Premio Turing), e nella sua carriera ha ricevuto cinque dottorati
ad honorem e numerosi altri riconoscimenti da università
ed associazioni.
È con grande soddisfazione, quindi, che ho
rivolto a Wirth alcune domande sul presente ed il futuro dello
sviluppo del software; come vedrete, Wirth ha opinioni molto ferme
sull'argomento, e le esprime con assoluta decisione.
D
Prof. Wirth, lei è stato uno degli accademici
più influenti degli ultimi decenni. Il suo lavoro ha avuto
un enorme impatto sia sull'insegnamento e la ricerca, sia sulla
pratica dello sviluppo del software. Tuttavia, in molti casi le
università ed "il mondo reale" sono, in effetti,
due mondi separati. Quando ho l'occasione di parlare con un professore
e con un programmatore, vedo fin troppo spesso che essi pensano
al software in modi totalmente diversi. Anche una recente ricerca
dell'IEEE su "il futuro del software" ha sostanzialmente
dimostrato che non vi è alcuna intersezione tra le opinioni
degli accademici e dei professionisti del software. Come uno dei
pochi il cui lavoro ha influenzato entrambi i campi, qual è
la sua opinione (o forse il suo segreto)?
R
Se vi è stato un segreto, è stato di
essere sia un programmatore che un professore. La suddivisione
tra i due campi è la sfortunata causa di tanti problemi.
I professori tipicamente spendono molto del loro tempo in riunioni,
pianificazioni, politica, proposte, ricerca di fondi, consulenze,
colloqui, viaggi, eccetera, ma relativamente poco progettando
realmente. Di conseguenza, spesso perdono il contatto con gli
aspetti concreti del loro campo (che evolve rapidamente), perdono
la capacità di progettare, la visione di cosa sia realmente
essenziale, e si rassegnano ad insegnare problemi accademicamente
interessanti.
Io non ho mai progettato un linguaggio per il desiderio
di farlo, ma solo perché avevo una necessità reale
che non sarebbe stata soddisfatta dai linguaggi disponibili. Ad
esempio, Modula ed Oberon sono stati sottoprodotti della progettazione
delle workstation Lilith (1979) e Ceres (1986). Il fatto che fossi
un insegnante ha avuto un'influenza decisiva nel creare linguaggi
e sistemi "il più semplici possibile" per poter
concentrare i miei insegnamenti sull'essenza della programmazione,
anziché sui dettagli dei linguaggi o delle notazioni.
Anche secondo me la lenta, costante separazione dell'accademia
dalla pratica della programmazione è deleteria.
D
Le è probabilmente familiare il concetto di
"software abbastanza buono"1 reso popolare da Yourdon.
A guardar bene, è più che altro una razionalizzazione
di ciò che sta avvenendo nel mondo del software: la prima
società che arriva sul mercato con un prodotto ricco di
funzionalità ha maggiori probabilità di "vincere
la guerra" rispetto ad un produttore attento, che ricerchi
la qualità dei prodotti.
Pensa che ci sia nulla che gli sviluppatori ed i
produttori di software possano fare per contrastare il fenomeno?
Io credo che molti sviluppatori sarebbero felici di avere più
tempo e poter così sviluppare software migliore, ma in
fondo la loro società deve sopravvivere sul mercato. "Educare
gli utenti" mi sembra più un sogno che una reale possibilità...
R
L'errore di fondo è che il "software
abbastanza buono" di rado è abbastanza buono. È
invece la triste manifestazione dei tempi moderni, in cui l'orgoglio
degli individui per il loro lavoro è diventato raro. L'idea
che si debba trarre soddisfazione dal successo del proprio lavoro,
perché quel lavoro è geniale, bello, o semplicemente
piacevole, è stata col tempo ridicolizzata. Solo il successo
economico, il riconoscimento in denaro è accettabile. Quindi
le nostre occupazioni diventano dei semplici "lavori".
Ma la qualità dei prodotti può essere ottenuta solo
attraverso la soddisfazione personale, la dedizione ed il piacere
di fare. Nella nostra professione, precisione e perfezione non
sono un lusso di cui si può fare a meno, ma una pura necessità.
R
Da tempo è in corso un dibattito su "l'ingegneria
del software come professione". In effetti, moltissime persone
che lavorano nello sviluppo del software non hanno mai avuto una
adeguata formazione, o esperienze significative. Pensa che i software
engineer debbano avere un albo, passare degli esami di qualificazione,
esattamente come gli altri ingegneri? C'é qualcosa nel
curriculum degli informatici o degli ingegneri che dovrebbe essere
cambiato per renderli più adatti al loro lavoro? Secondo
lei, quale è la formazione ideale che per un futuro software
engineer?
R
Recentemente ho letto il rapporto finale di un progetto
di ricerca finanziato dalla Swiss National Science Foundation.
Le finalità (ingenue) del progetto erano di investigare
i seguenti punti:
D
Sempre a proposito di formazione, molte persone pensano
che sia più semplice imparare il paradigma ad oggetti se
non si è stati esposti in precedenza ad altri paradigmi.
Questo mi sembra un grave errore, perché uno sviluppatore
esperto dovrebbe avere una conoscenza di altri paradigmi oltre
a quello usato, ad esempio il paradigma funzionale o quello logico.
Inoltre, credo che i primi lavori sull'ingegneria del software,
ad esempio gli scritti di Parnas, e alcuni classici della programmazione
come il suo "Principi di Programmazione Strutturata"
siano utili oggi come lo erano anni fa. Qual è la sua opinione?
R
Molte persone tendono a vedere i linguaggi e gli
stili di programmazione sotto un'ottica religiosa. Se appartieni
ad una confessione, non puoi appartenere alle altre. Ma questa
analogia è un altro grande errore, sostenuto solo da ragioni
di tipo economico.
La programmazione orientata agli oggetti è
solidamente basata sui principi ed i concetti della programmazione
procedurale tradizionale. L'OOP non ha aggiunto alcun nuovo concetto,
ma ha spostato l'enfasi su due concetti, in modo molto più
forte di quanto accadeva nella programmazione procedurale.
Il primo concetto è quello della procedura
legata ad una variabile strutturata, chiamata oggetto; il fatto
che la procedura sia ora legata ad una variabile ha giustificato
il fatto che fosse rinominata in metodo. Ma il significato di
questo legame è la variabile di tipo procedura, un concetto
apparso nei linguaggi di programmazione alla metà degli
anni settanta. Il secondo concetto è quello di costruire
un nuovo tipo di dato (chiamato sottoclasse) estendendo un altro
tipo (la superclasse).
Vale la pena di notare che con il paradigma object
oriented è stata introdotta una terminologia completamente
nuova, con lo scopo di mistificare le radici dell'OOP. Quindi,
dove una procedura era attivata "chiamandola", ora si
"manda un messaggio al metodo". Un nuovo tipo non è
più costruito "estendendone" un altro, ma definendo
"una sottoclasse che eredita la superclasse".
Un fenomeno interessante è però che
molte persone hanno appreso per la prima volta le importanti nozioni
di tipo di dato, di incapsulazione, e (forse) di information hiding
quando sono state introdotte alla programmazione ad oggetti. Questo
da solo ha reso l'introduzione all'OOP importante, anche se non
si facesse uso dell'OOP in futuro. In ogni caso, io considero
l'OOP come un aspetto del "programming in the large",
quindi un asepetto che dal punto di vista dell'insegnamento segue
il "programming in the small" e richiede una solida
conoscenza della programmazione procedurale. La modularità
a livello statico è il primo passo verso l'OOP, ed è
molto più semplice da capire e padroneggiare che l'intera
OOP. In molti casi, è anche sufficiente per scrivere del
buon software, anche se purtroppo non è supportata in molti
linguaggi di uso comune, ad eccezione di Ada.
In un certo senso, l'OOP non mantiene tutte le sue
promesse. Il nostro fine ultimo è l'extensible programming.
Con ciò intendiamo la costruzione di gerarchie di moduli,
dove ogni modulo aggiunge funzionalità al sistema. Extensible
programming implica che l'aggiunta di un modulo sia possibile
senza alcuna modifica nei moduli esistenti. Essi non dovrebbero
neppure essere ricompilati. I nuovi moduli aggiungono non solo
nuove procedure ma anche e soprattutto nuovi tipi di dato (estesi).
Noi abbiamo dimostrato che questo approccio è percorribile
ed economico, con il progetto del Sistema Oberon2.
D
Recentemente mi è capitato di vedere una pubblicità
di Borland Delphi (che come sa è un Pascal ad oggetti con
estensioni per la gestione degli eventi), che diceva testualmente
"Delphi 2.0 dà agli sviluppatori un linguaggio quasi
leggibile come il BASIC...". Credo fosse una citazione da
una prova del prodotto pubblicata su PCWeek. Però mi è
sembrata così terribilmente sbagliata: "quasi leggibile"
come un linguaggio senza una vera nozione di tipo di dato? D'altra
parte, non possiamo nascondere il fatto che in larga parte il
Basic (Visual Basic) abbia vinto sul mercato, e che sia probabilmente
il primo esempio di un linguaggio commerciale con un enorme mercato
di componenti. Come padre del Pascal, qual è la sua opinione?
Il Basic ha realmente vinto? Perche?
R
Bisognerebbe essere molto cauti nell'uso di termini
come "leggibile", "user friendly", eccetera.
Sono termini vaghi nel migliore dei casi, e di solito si riferiscono
ad abitudini ed opinioni personali. Ma ciò che è
convenzionale non è necessariamente migliore. Nel contesto
dei linguaggi di programmazione, credo che "leggibile"
dovrebbe essere sostituito da "adatto ad un ragionamento
formale". Ad esempio, difficilmente potremmo dire che le
formule matematiche sono un esempio di alta leggibilità,
ma esse permettono una derivazione formale di proprietà
che non sarebbe ottenibile da una formulazione vaga, confusa,
informale, ma "user friendly".
Un costrutto come WHILE B DO S END ha l'interessante
proprietà che chi lo scrive può essere certo che
B sia falsa quando il comando è stato eseguito. E se troviamo
una proprietà P che è lasciata inalterata da S (invariante),
si può essere certi che anche P sia inalterata dopo la
terminazione. È questo tipo di ragionamento che aiuta nella
derivazione sicura dei programmi, e che riduce radicalmente
il tempo perso nel testing e debugging.
I buoni linguaggi non si basano solo su concetti
matematici, che rendono possibile un ragionamento logico sui programmi,
ma anche su un piccolo numero di concetti e regole che possono
essere combinati in vari modi. Se la definizione di un linguaggio
richiede spessi manuali di centinaia di pagine, e la definizione
si riferisce ad un modello "meccanico" dell'esecuzione
(un computer), questo deve essere visto come un sintomo di inadeguatezza.
Ma sfortunatamente, in questo senso l'Algol nel 1960 era più
avanzato di molti dei suoi successori, in particolare di quelli
che oggi sono così popolari.
D
Un altro linguaggio molto popolare è il C++.
So bene che lei non lo ama particolarmente, e che in certi casi,
un linguaggio più sicuro potrebbe essere una scelta migliore.
Tuttavia, a volte mi chiedo se non sarebbe più saggio aiutare
i programmatori invece di combatterli. Ad esempio, in molti casi
i programmatori C++ sarebbero felici di usare una versione più
restrittiva ma più sicura del linguaggio: non tutti sono
così preoccupati di una compatibilità al 100% con
il C. Una versione del C++ dove puntatori e array siano chiaramente
distinti, e dove il compilatore emetta un warning se (ad esempio)
si assegna un float ad un long, e così via, li aiuterebbe
a scrivere programmi migliori senza dover imparare un linguaggio
completamente nuovo. Capisco che sia più interessante progettare
un linguaggio "puro" da zero piuttosto che cercare di
renderne uno "fragile" più sicuro, ma se poi
solo un gruppetto di persone finisce per usare il nuovo linguaggio,
stiamo veramente facendo progredire lo stato dello sviluppo del
software?
R
Il mio compito come insegnante è di formare
ed educare i futuri programmatori. Per fare questo al meglio,
io presento le nozioni fondamentali nel modo più chiaro
e succinto possibile. Dal canto mio, non voglio che una notazione
inadeguata possa limitarmi nei miei compiti. Se gli studenti hanno
afferrato le idee fondamentali ed hanno guadagnato una certa versatilità
e familiarità con il soggetto, non trovano difficoltà
ad adeguarsi ad altri linguaggi se necessario (anche se spesso
si lamentano delle loro inadeguatezze). Non mi sembra che questo
sia lottare contro i programmatori.
Ci si dovrebbe chiedere come mai nessuno, nella grande
industria del software, ha intrapreso il progetto di definire
un sottoinsieme sicuro del C++. Io posso immaginare solo due ragioni:
la prima è che il mondo del software sia interessato a
linguaggi "più potenti", non a sottoinsiemi restrittivi.
La seconda è che simili tentativi falliscano come i tentativi
di rinforzare la struttura di una casa costruita sulla sabbia.
Ci sono cose che non si possono aggiungere a posteriori.
D
Per concludere: non le sembra che la comunita degli
sviluppatori (nel senso più ampio) si preoccupi troppo
di questioni tecniche, dimenticando che lo sviluppo del software
è più che altro una attività umana? Ad esempio,
io credo che una delle ragioni per la popolarità del Basic
e del C sia che la loro relativa mancanza di restrizioni permette
l'introduzione di "soluzioni locali" (eufemismo per
rattoppi) anche in uno stato avanzato dello sviluppo. Sappiamo
tutti che dovremmo progettare accuratamente il software prima
di passare alla codifica. Ma sappiamo anche bene che (in molti
casi) il management non vuole pagare adesso per dei benefici
a lungo termine (questa è una delle ragioni per cui alcuni
non si trovano bene con l'OOP). Di conseguenza, il software è
abitualmente "rattoppato" quando si trova già
in uno stato di sviluppo piuttosto avanzato, ed i linguaggi che
permettono di fare ciò senza troppi problemi vengono usati
più diffusamente rispetto a quelli che richiedono un grande
investimento nel design iniziale.
Ma allora noi continuiamo a incolpare i programmatori
di essere "sporchi", quando in effetti stanno semplicemente
lavorando nel mondo reale, non in un mondo ideale. Non sarebbe
meglio pensare ai linguaggi di programmazione con più considerazione
per i fattori umani? A me sembra che diversi linguaggi di programmazione
moderni siano talmente ricchi che molti programmi faranno uso
(al più) del 20% del linguaggio. Ma molte delle nuove feature
portano solo a maggiore flessibilità, non ad una maggiore
sicurezza. Ad esempio, la vecchia regola "dichiara prima
di usare" è stata introdotta nei linguaggi riconoscendo
che i programmatori commettono degli errori, ed imponendo quella
regola si consente ai compilatori di trovare alcuni di quegli
errori. Nello stesso senso, la clausola "obsolete" in
Eiffel è un riconoscimento del fatto che alcune funzioni
e porzioni del codice diventano obsolete, ma senza (almeno) un
warning a tempo di compilazione, molti programmatori continueranno
ad utilizzarle: chi ha tempo di leggere commenti e documentazione
delle funzioni, quando il prodotto doveva essere pronto ieri?
Tuttavia, mentre ho potuto assistere ad infervorati
dibattiti sull'utilità o meno di introdurre la clausola
"finally" in C++, ho visto ben poco interesse per nuovi
meccanismi che permettano di proteggere il programmatore (come
essere umano) da se stesso...
R
Lo sviluppo del software è una attività
tecnica svolta dagli esseri umani. Non è un segreto che
gli esseri umani soffrano di imperfezione, limitata affidabilità,
ed impazienza - tra le altre cose. Aggiungiamo che sono diventati
anche pretenziosi, il che porta a richieste di rapidità
ed alta produttività che compensino gli alti salari richiesti.
Lavorare sotto costante pressione, tuttavia, porta a prodotti
insoddisfacenti ed errati. In genere, la speranza è non
solo che le correzioni saranno facili, perche il software è
immateriale, ma che i clienti saranno disposti a condividerne
il costo.
Esistono metodi migliori per progettare il software
rispetto alla pratica comune, ma questi sono raramente seguiti.
Io conosco personalmente una grande azienda produttrice di software,
che assume esplicitamente che il design richieda il 20%, ed il
debugging l'80%, del tempo dei suoi impiegati. Ciò nonostante
alcune persone al loro interno abbiano dimostrato che un rapporto
di 80% design, 20% debugging sia non solo realistico, ma anche
in grado di migliorare l'immagine un po' compromessa della compagnia.
Perché, allora, preferiscono l'approccio con il 20% di
design? Perché con il 20% di design il prodotto raggiunge
il mercato prima di un concorrente che spenda l'80% del tempo
in design. E le indagini dimostrano che una larga parte dei clienti
preferisce avere un prodotto traballante subito, piuttosto che
attendere un prodotto più stabile e maturo. Chi dobbiamo
incolpare per questo stato delle cose? Il programmatore che è
diventato un hacker, il manager sotto pressione, gli affaristi
che cercano di estrarre profitto ovunque sia possibile, o il
cliente che crede nei miracoli promessi?
Per quanto riguarda la seconda parte della domanda,
ed i commenti sul design dei linguaggi di programmazione in funzione
dei fattori umani: l'abbondanza di funzionalità in tanti
linguaggi è in effetti un problema, non una soluzione.
La "featurity" è un'altra conseguenza della
credenza dei programmatori che il valore di un linguaggio sia
proporzionale alla quantità di costrutti e funzionalità,
varie ed eventuali. Tuttavia, noi sappiamo che è meglio
se ogni concetto di base è rappresentato da un unico, ben
determinato costrutto del linguaggio. Non solo questo riduce lo
sforzo di apprendimento, ma riduce anche il volume della descrizione
del linguaggio e quindi le possibilità di inconsistenza
e di interpretazioni erronee. Mantenere un linguaggio il più
semplice e regolare possibile è stato sempre uno dei miei
criteri di lavoro; la descrizione del Pascal richiede circa 50
pagine, quella del Modula 40, e Oberon solamente 16 pagine. Questo
è quello che io considero un reale progresso.
Il valore maggiore dei linguaggi ad alto livello
è la qualità e l'adeguatezza delle astrazioni che
ci offrono. Un esempio è l'astrazione che chiamiamo numero,
o quella di un valore di verità, che rimpiazzano le stringhe
di bit "concrete" che le sottendono. Nel caso dei numeri,
solo le operazioni aritmetiche dovrebbero essere applicabili,
indipendentemente dal fatto che anche le operazioni logiche potrebbero
essere usate sulle stringhe di bit che rappresentano i numeri.
Un altro caso è la nozione di array con un certo numero
di elementi che possono essere indirizzati con un indice valido,
indipendentemente dal fatto che l'indirizzo risultante sia un
puntatore ad una zona di memoria. L'astrazione di cui parlo in
questo caso è quella di tipo di dato, e sottolineo che
il valore di questa astrazione è basato sul fatto che il
compilatore controllerà che le regole che governano quel
tipo di dato siano rispettate, ovvero che il compilatore garantirà
l'integrità dell'astrazione. Se un sistema fallisce nel
fare questo, se permette di applicare operazioni logiche sui numeri,
o se non individua l'accesso ad un array con un indice invalido,
tanto per fare qualche esempio, allora non merita di essere chiamato
un linguaggio ad alto livello. Tuttavia, i linguaggi più
usati hanno esattamente questa natura, e offrono astrazioni che
possono essere liberamente violate, aggiungendo come compensazione
innumerevoli strumenti che permettono di ispezionare la struttura
interna delle astrazioni, in modo da scoprire cosa sia andato
storto.
È particolarmente ironico che linguaggi con
schemi strutturali fissi per i comandi ed i tipi di dato, con
costrutti moderni per la modularità e l'information hiding,
siano spesso giudicati restrittivi, complicati, e "limitativi
per la creatività". Invece, programmare con un linguaggio
strutturato e fortemente tipato richiede normalmente di prendere
un maggior numero di decisioni accurate, e questo è considerato
dannoso (ricordiamo che la programmazione deve essere pubblicizzata
come semplice). L'ironia sta nel fatto che il tempo guadagnato
non dovendo sottostare a regole strutturali è spesso più
che compensato dal tempo perso cercando gli errori a posteriori
- sul campo, e magari presso un cliente insoddisfatto.
Non vedo però molti cambiamenti all'orizzonte.
I concetti ed i linguaggi che permetterebbero l'effettiva evoluzione
della programmazione in una seria disciplina ingegneristica sono
stati con noi per anni, ma sono rimasti largamente inutilizzati,
e gli sviluppi più recenti sembrano portare ancora più
lontano da essi. Credo che la programmazione rimarrà il
paradiso degli hacker ancora per parecchio tempo; sicuramente,
i computer non si lamenteranno.
Ricordo una lunga discussione durante un seminario
accademico nella metà degli anni settanta, quando il termine
"crisi dei software" era continuamente sbandierato e
la nozione di prova di correttezza dei programmi era stata avanzata
come possibile rimedio. Il seminario era tenuto dal Prof. C.A.R.
Hoare, che ne aveva eloquentemente presentato i principi, ed anche
i vantaggi ottenibili rimpiazzando il testing con una dimostrazione
di correttezza. Dopo una lunga discussione sui pro ed i contro,
Jim Morris si alzò e chiese in modo disarmante: "Ma
Tony, cosa rispondi se ti confessiamo sinceramente che noi amiamo
il debugging? E tu vorresti che abbandonassimo il nostro più
caro divertimento?".
Tuttavia, sono convinto che ci sia una necessità
per software di alta qualità, e che arriverà un
momento in cui verrà riconosciuto che vale la pena di compiere
degli sforzi per svilupparlo, così come di investire nell'uso
attento di un approccio strutturato, basato su linguaggi strutturati
e sicuri. Nell'immediato futuro, tuttavia, questo sarà
vero solo per alcuni prodotti di nicchia. Le nicchie si espanderanno
quando un numero crescente di persone esprimerà apertamente
l'insoddisfazione derivante dal software scadente.
Biografia [1] [2]
Carlo Pescio (pescio@acm.org) svolge attività di consulenza in ambito internazionale nel campo
delle tecnologie Object Oriented. Ha svolto la funzione di Software Architect in grandi progetti per
importanti aziende europee e statunitensi. È incaricato della valutazione dei progetti dal
Direttorato Generale della Comunità Europea come Esperto nei settori di Telematica e Biomedicina.
È laureato in Scienze dell'Informazione ed è membro dell'ACM, dell'IEEE e della New York Academy
of Sciences.
"Good Enough Software". Si veda ad esempio Yourdon, "Rise and Resurrection of the American
Programmer", Yourdon Press, 1996. Si tratta fondamentalmente di produrre il piu’ rapidamente
possibile software che sia abbastanza privo di errori da poter essere utilizzato, un modello
non molto dissimile da quello di Microsoft.
Wirth N. and J. Gutknecht, "Project Oberon", Addison-Wesley, 1992.