Hai mai provato a dialogare con un neonato? È molto complesso, perché lui può risponderti solo con due stati: sorride, beato, quando tutto va bene; piange, disperato, se qualcosa è andato storto. Il suo è un linguaggio che risponde esclusivamente agli stimoli del suo corpo. Un computer è un (dotatissimo) neonato in vetronite e rame a cui dobbiamo spiegare “come fare le cose” con minuzia di particolari, istruzione dopo istruzione. Se lavorassimo esclusivamente sui suoi stati primordiali, 0 e 1, impiegheremmo un’eternità per rilasciare un’applicazione che vada oltre l’iconico “Hello World!”.
Per fortuna ci sono i linguaggi di programmazione: gli sviluppatori dispongono di vocabolari e regole di sintassi con cui risolvere problemi di qualunque natura – dalla prossima fattura da emettere alla stima delle condizioni del suolo lunare – e mettere gli elaboratori nelle condizioni di usare al meglio le proprie capacità di calcolo.
Non è stato sempre così. Riavvolgiamo il nastro e guardiamo da vicino gli oltre 70 anni di storia dei linguaggi di programmazione. Si tratta di un’evoluzione molto simile all’apprendimento della parola negli esseri umani: siamo passati da forme di linguaggio semplici, a basso livello, dalle ridotte capacità espressive a forme più sofisticate, con cui poter astrarre concetti complessi e sviluppare software con relativa semplicità.
I primi vagiti dei linguaggi di programmazione: linguaggio macchina e Assembly
Anni ’40. I primissimi computer sono tanto ingombranti quanto poco capaci di comprendere qualcosa che vada oltre lunghe, anche lunghissime, sequenze di bit. Chi ha l’arduo compito di programmare deve semplicemente (!) settare ogni singolo bit su 0 e 1 e attendere con fiducia il risultato.
Stendiamo un velo pietoso su quello che doveva essere il debug – del resto, chi non impazzisce davanti a un bambino che piange nonostante i nostri tentativi di farlo desistere? – e focalizziamoci su quanto impegnativo debba essere lo sviluppo software in queste condizioni. Ogni computer, come ogni neonato, funzionava “a modo suo”: era pressoché impossibile programmare due macchine diverse senza prima aver studiato a fondo il funzionamento di entrambe. Un incubo.
La nascita dei linguaggi Assembly (1947, ARC Assembly) migliora leggermente la vita dei pionieri dello sviluppo. I programmatori dispongono finalmente di comandi – ADD, MOV, INT – che l’elaboratore traduce in sequenze di bit prima dell’esecuzione. Un timido passo in avanti ma pur sempre un linguaggio a basso livello, dipendente dalla macchina su cui si esegue. Siamo nella fase in cui il bambino ha appena imparato a dire mamma, papà, pappa.
I primi linguaggi di programmazione ad alto livello: Fortran, Cobol e Basic
Anni ’50. L’avvento di compilatori e interpreti è la scintilla che indirizza lo sviluppo verso ciò che conosciamo oggi. I linguaggi di programmazione acquisiscono umanità. Gli informatici del tempo comprendono che dev’essere l’elaboratore, e non lo sviluppatore, a doversi avvicinare alle persone, sprecare qualche risorsa in più e tradurre il codice sorgente in linguaggio macchina.
Nel 1957 un gruppo di programmatori IBM guidati dall’ingegnere John Backus pubblica il Fortran. L’origine del nome – acronimo di Formula Translator – spiega alla perfezione lo scopo del linguaggio, ovvero semplificare la codifica di calcoli scientifici. Nel 1960 arriva il Cobol – Common Business-Oriented Language – per sviluppare applicazioni per l’ambito amministrativo e commerciale. A seguire, nel 1964, compare il Basic, pensato per avviare i principianti ai rudimenti della programmazione. Sarà un successo.
A differenza dell’Assembly, ogni istruzione in Fortran, Cobol e Basic corrisponde a più operazioni in linguaggio macchina. Il codice sorgente è organizzato in blocchi – subroutine, procedure e/o funzioni – ed è governato da strutture di controllo elementari: sequenze e salti condizionati (goto). Si ottengono listati di codice più comprensibili ma, fra un if e un goto, seguire la sequenza logica dei programmi è complesso come sciogliere un groviglio di spaghetti. Metafora da cui deriva l’espressione denigratoria che definisce le cattive abitudini di programmazione: lo spaghetti coding.
Il bambino ha imparato a parlare, formula frasi di senso compiuto ma non è ancora in grado di articolare discorsi complessi.
La programmazione strutturata: arriva il Pascal
Nel 1966 si afferma il teorema di Böhm e Jacopini: per implementare qualunque algoritmo è sufficiente ricorrere a 3 strutture di controllo, ovvero sequenze, selezioni e iterazioni. Sono le basi teoriche della programmazione strutturata, il chiavistello che segrega negli anni ’60 la prassi del salto condizionato in nome dell’efficacia e della leggibilità del codice.
Il Pascal, nato nel 1970 grazie al lavoro di Niklaus Wirth, è il figlio di maggior successo del nuovo paradigma. Concepito per finalità didattiche, con una tipizzazione forte e una struttura sintattica particolarmente rigida, il Pascal sbarca presto nell’industria informatica: viene addirittura usato per scrivere parti del sistema operativo del Macintosh e di Microsoft Windows.
Il bambino adesso sa articolare discorsi più complessi. Le performance non sono il massimo poiché ha pur sempre bisogno di un compilatore o di un interprete per farsi capire. Ma continua a crescere.
Sua maestà il C
Pascal e Basic allargano la platea di sviluppatori. Entrambi però non permettono di sfruttare al massimo le potenzialità degli elaboratori dell’epoca. Con un parallelismo forse ardito, così come poeti e scrittori forzano la lingua per esplorare territori nuovi, così uno sviluppatore esperto si aspetta un linguaggio malleabile e potente per realizzare applicazioni performanti.
Il C è la risposta. Coevo del Pascal, il C viene sviluppato da Dennis Ritchie fra il 1969 e il 1973 come base per riscrivere il kernel di UNIX. Versatile nella rappresentazione dei dati, antitesi del Pascal e della sua tipizzazione forte, il C permette operazioni sofisticate e complesse pur disponendo di pochi strumenti. È diretto come il linguaggio macchina, grazie ai puntatori, ma più semplice da usare – per un utente esperto – e, soprattutto, è portabile su più sistemi. Non a caso il C è stato per anni il linguaggio d’elezione per sviluppare sistemi operativi, librerie, giochi e applicazioni altamente performanti.
La programmazione a oggetti: C++ e Java
1983, Bell Laboratories. Dal lavoro di Bjarne Stroustrup nasce il C++, evoluzione del C, e con esso una rivoluzione nel modo di progettare e sviluppare software: la programmazione orientata agli oggetti o OOP (Object Oriented Programming). I team di sviluppo hanno finalmente a disposizione strumenti che distinguono logicamente i contenuti (le variabili e i record) dalle interfacce (i metodi e le funzioni). Un maggiore livello d’astrazione che agevola leggibilità, scalabilità e manutenzione del codice sorgente. Un successo adottato nella scrittura del codice da importanti produttori di software, da Apple a Adobe.
Nel 1992 è il turno di Java, che eredita sintassi e stile di C++ al netto di quelle che furono giudicate “inutili complessità”, come l’aritmetica dei puntatori e l’ereditarietà multipla delle classi. La filosofia di Java – write once, run anywhere – ne compromette in parte l’efficacia in termini di performance: il codice viene prima compilato in bytecode quindi interpretato in una Java Virtual Machine (JVM). Ciò comunque non impedisce alla creatura del team di James Gosling di issarsi ai vertici dei linguaggi più usati nel mondo.
Java ha inoltre contribuito alla dinamizzazione delle pagine web. La JVM di Netscape ha infatti reso possibile la realizzazione di applet da scaricare ed eseguire sui client. Da diffusa biblioteca di documenti, Internet si evolve a ludoteca e luogo di incontri digitali con i primi giochi e le primissime chat.
I linguaggi di scripting per il web: PHP e JavaScript
Il nostro bambino ha imparato a parlare, formulare ragionamenti complessi e astratti. Con l’avvento del web ha iniziato a girare il mondo, senza paura di farsi comprendere.
PHP è scritto in C. Nasce nel 1994 come collezione di script CGI e si evolve, pian piano, in quello che è oggi: dapprima un preprocessore di pagine ipertestuali – dall’acronimo Hypertext Preprocessor – quindi un linguaggio per la programmazione di applicazioni stand-alone. Insieme ad ASP, realizzato da Microsoft, contende lo scettro del linguaggio di programmazione più usato per le applicazioni lato server.
JavaScript, a dispetto del nome, non ha nulla a che vedere con Java, se non per la sintassi ispirata a C. Grazie all’avvento di alcuni diffusissimi framework – jQuery, AngularJS, React – sta vivendo una seconda giovinezza ed è, assieme a HTML5 e CSS, il linguaggio di programmazione utilizzato per Instant Developer Cloud. Da semplice gestore degli eventi lato client a linee di codice JavaScript che permettono il caricamento asincrono di dati ed elementi HTML nelle pagine web.
I linguaggi per le app mobile: Objective-C, Swift e… Java
L’ultimo capitolo di questa storia inizia con l’arrivo sul mercato di smartphone e tablet. Due i sistemi operativi a contendersi il mercato: Android, installato su buona parte dei dispositivi, e iOS, presente su iPhone e iPad. Due mondi che non si parlano mai.
Una bella gatta da pelare per gli sviluppatori, soprattutto in ottica portabilità: per realizzare la stessa applicazione nativa per i due sistemi operativi occorre conoscere almeno 2 linguaggi di programmazione: il sempre vivo Java – e volendo C++ – per il mondo Android; Objective-C e il più recente Swift per iOS.
Per aggirare le difficoltà vengono concepiti, sviluppati e diffusi diversi framework che permettono con un unico sviluppo di realizzare app cross platform ibride, come ad esempio Apache Cordova e React Native. I framework si occupano di impacchettare web-app realizzate in HTML5, CSS e JavaScript in applicazioni che si interfacciano tramite API all’hardware dei dispositivi. Eppure si può fare ancora un passo in più: alcune piattaforme di sviluppo come Instant Developer Foundation e Instant Developer Cloud consentono di andare ben al di là del semplice “framework che impacchetta”, consentendo di gestire tutto il processo, a partire dalla fase di analisi fino al momento della pubblicazione.
Conclusioni: la babele dei linguaggi di programmazione
Non esiste una Stele di Rosetta in grado di contenere sulle sue facce gli oltre 8.000 linguaggi di programmazione che si sono succeduti negli anni, molti ormai scomparsi e moltissimi altri resilienti che resistono nonostante l’obsolescenza tecnologica degli elaboratori con cui sono stati sviluppati. Per esempio Python, nato all’inizio degli anni ‘90, incontra ancora il favore di una buona parte degli sviluppatori.
Oppure la Programmazione Orientata agli Aspetti o AOP (Aspect Oriented Programming), un paradigma nato sempre alla fine dello scorso millennio, che viene utilizzato per ampliare concetti e costrutti dell’OOP.
In conclusione, l’evoluzione dei linguaggi e degli approcci di programmazione è funzione diretta dei problemi che i programmatori sono chiamati a risolvere. Più le necessità diverranno specifiche, più il nostro bambino apprenderà parole e metodi nuovi.
C’mon, let’s code.
Si è dimenticato uno dei linguaggi più usati e completi che ci siano, erede di C e C++, il C#.
Linguaggio di elezione per l’ambiente di sviluppo MS .Net.
Superiore a tantissimi altri linguaggi e che consente di programmare dappertutto, da Windows, al Web, al Mobile.