Storia della programmazione

A differenza di altri strumenti, realizzati per compiti più o meno specifici, il computer è uno strumento “universale”, il cui compito è definito dalla preventiva formulazione di specifiche sequenze di istruzioni. Queste sequenze vengono chiamate programmi, o codice, o applicazioni (app), e vanno progettate in modo rigoroso, assicurando di fornire alla macchina tutti i comandi necessari, in modo da gestire correttamente ogni possibile situazione, evitando ambiguità o incongruenze.

La realizzazione di un programma è articolata su più fasi: dalla definizione dei requisiti, alla attività di codifica vera e propria delle istruzioni, alla attività di collaudo e ottimizzazione delle prestazioni.

L’insieme di tutti questi aspetti può essere definita programmazione, o sviluppo software. E’ una “nuova” attività umana, nata con l’avvento dei calcolatori elettronici a programma memorizzato. Caratterizzata da un significativo impegno di risorse umane “intellettuali”, comprende aspetti ingegneristici e teorici, richiede rigore logico ma anche creatività.

Le Basi (per non addetti ai lavori)

Linguaggio di basso e alto livello

L’hardware del computer viene comandato da sequenze di bit, e anche i dati da trattare sono sequenze di bit. Ogni tipo di computer ha le sue regole per comprendere il significato dei bit delle istruzioni, e per distinguere i dati dalle istruzioni.

I primi programmatori dovevano quindi conoscere la struttura del computer utilizzato, e impostare in memoria (ad esempio con interruttori, nastro di carta perforato, schede di cartoncino perforate) il valore di ogni singolo bit, sia per le istruzioni che per i dati. Attività impegnativa e lenta, che richiedendo conoscenze specialistiche, avrebbe drasticamente ridotto il numero dei potenziali utilizzi dei computer. .

Occorreva quindi sviluppare dei linguaggi più semplici da utilizzare, simili ai linguaggi “simbolici” utilizzati dagli umani, dotati dei propri vocaboli e delle proprie regole, cioè una grammatica. Ma i linguaggi umani, utilizzati da esseri intelligenti, funzionano anche con le loro eccezioni, ambiguità, interpretazioni; i linguaggi per computer avrebbero dovuto essere rigorosi, tener conto di ogni possibile dettaglio, sino a livello di un singolo bit.

La prima soluzione fu di definire brevi istruzioni composte da nomi mnemonci (ad. es. ADD, MOV, FWD); ciascuna produceva la corrispondente sequenza di bit in linguaggio macchina. Questi linguaggi, chiamati “assembly” erano ancora specifici per le caratteristiche dell’hardware di ciascuna macchina, e comunque ancora molto onerosi in termini di tempi e costi di utilizzo.

La seconda soluzione fu quindi lo sviluppo di linguaggi con una impostazione più simile a quelle dei linguaggi umani, e sopratutto che fossero indipendenti dall’hardware utilizzato . Questi linguaggi comprendevano un vocabolario con istruzioni più complesse, ciascuna poi convertita automaticamente nelle numerose istruzioni in linguaggio macchina. Questi linguaggi, per contrapposizione ai “semplici” linguaggi assembly (definiti anche “di basso livello”) vennero pertanto definiti “di alto livello”.

Linguaggio interpretato o compilato

La fase di conversione delle istruzioni scritte dal programmatore (codice sorgente) alla sequenza di bit (linguaggio macchina) che verrà eseguita dall’hardware può avvenire secondo due modalità:

  • linguaggio interpretato: quando il programmatore avvia l’esecuzione del programma, ogni istruzione viene letta, convertita in bit ed eseguita;
  • linguaggio compilato: le istruzioni del programma vengono preventivamente date in ingresso (come normali dati da elaborare) ad un apposito programma (definito compilatore) che produce come risultato in uscita una sequenza di bit. E’ questa sequenza (un normale file di dati) che in un secondo momento verrà “eseguita” dall’hardware.

Ciascuno dei due tipi di linguaggio presenta limiti e pregi, e viene utilizzato per compiti diversi. Il linguaggio interpretato ha prestazioni inferiori, ma è facilmente modificabile; adatto quindi a programmi di piccole dimensioni, applicazioni sperimentali e interattive.

Il linguaggio compilato, più efficente, è quello normalmente utilizzato nei programmi di uso comune e di maggiori dimensioni, quelli caricati su server, PC o smartphone. Inoltre il linguaggio compilato evita la distribuzione del codice sorgente, che rappresenta il grande valore intellettuale ed economico sottostante alla sua scrittura.

Senza la possibilità (seppur non perfetta) di proteggere il codice sorgente non esisterebbe la produzione di software come la conosciamo oggi, con con tutte le implicazioni economiche e sociali che ne deriverebbero.

Le origini “meccaniche” della programmazione

L’idea di realizzare un dispositivo di calcolo meccanico programmabile va attribuita al matematico e scienziato inglese Charles Babbage, che già nel 1822 aveva annunciato la Macchina Differenziale (Difference Engine) in una presentazione alla Royal Society inglese dal titolo “Note on the application of machinery to the computation of astronomical and mathematical tables”.

Pur avendo ricevuto vari finanziamenti dal governo inglese per la costruzione di questa macchina (che procedette a rilento per vari anni e che non fu mai completata), Charles Babbage attorno al 1833 iniziò a dedicarsi alla progettazione di una ben più avanzata macchina, la Macchina Analitica (Analytical Engine).

Questa sarebbe stata una macchina di utilizzo più generale, programmabile tramite l’ utilizzo di schede perforate, del tipo di quelle già utilizzate da Joseph Marie Jacquard all’inizio del secolo sul suo telaio per tessitura. Anche se mai realizzata, questa macchina occupa un posto importante nella storia dei calcolatori programmabili moderni, avendone anticipato di oltre un secolo i concetti di base poi adottati, ancora validi ai nostri giorni.

La Macchina Analitica avrebbe avuto lo “store” (la memoria), il “mill” (l’unità di calcolo”) capace di eseguire le quattro operazioni, le comparazioni e opzionalmente le radici quadrate; questo avrebbe utilizzato le proprie procedure, memorizzate sotto forma di pioli inseriti in tamburi rotanti chiamati “barrels” (barili, contenitori), per eseguire alcune delle più complesse istruzioni che il programma dell’utente avrebbe potuto richiedere.

Il linguaggio di programmazione definito da Babbage era simile ad un attuale linguaggio assembly, e comprendeva la possiblità di specificare loops (cicli) e salti condizionali. Lo stesso Babbage scrisse due dozzine di programmi, relativi al calcolo di polinomiali, formule iterative, il metodo di eliminazione di Gauss, e numeri di Bernulli.

Naturalmente questi programmi furono scritti solo sulla carta, non essendo stata costruita la macchina.

Degna di nota fu anche anche la collaborazione con Ada Lovelace, matematica ed amica di Babbage, che non solo contribuì nel 1883 alla scrittura dei programmi per il calcolo dei numeri di Bernulli, ma anche descrisse, superando la visione dello stesso Babbage, come la Macchina Analitica avrebbe potuto elaborare simboli oltre che numeri, ipotizzandone quindi l’utilizzo in settori ben più ampi del calcolo.

La macchina analitica non verrà però mai realizzata, e le idee di Babbage e Ada cadranno in oblio per decenni.

Un altro esempio di programmazione meccanica sarà ideato solo a partire dal 1938 da un ingegnere meccanico tedesco, Konrad Zuse, che sviluppa una notazione per descrivere un programma per un calcolatore meccanico di sua costruzione, lo Z1: il Plankalkül (Calculus of plans). Nel 1945 descriverà il linguaggio in un libro, che a causa degli eventi bellici non fu mai pubblicato.

Con l’avvento dell’elettronica (il computer COLOSSUS in Inghilterra o l’ ENIAC in USA) la prima forma di programmazione era ancora “meccanica”, tramite la connessione manuale di cavi su un pannello, sullo stile dei vecchi centralini telefonici nei quali la connessione delle linee fra gli utenti era effettuata da operatori umani, normalmente donne.

Solo nel 1945 con la formulazione del concetto di “macchina a programma memorizzato” da parte team della Moore School di Filadelfia (Presper Eckert, John Mauchly, Henry Goldstine, John von Neumann) nasce la necessità della nuova attività della “programmazione”. Questa fu inizialmente sottostimata, sia per gli aspetti delle modalità di scrittura delle istruzioni (linguaggi), sia per difficoltà di collaudo.

Simbolico il commento di David Wheeler al suo primo impatto con la programmazione dell’ EDSAC all’università di Cambridge, primo computer a programma memorizzato: “….esitando all’angolo delle scale mi resi perfettamente conto che una buona parte del resto della mia vita sarebbe stata spesa a trovare gli errori dei miei stessi programmi“.


Fonti

error: