Alan Turing è un personaggio affascinante: uomo geniale e sensibile la cui morte è contornata di mistero e leggenda. Negli anni 30 fonda i principi dell'informatica teorizzando il primo computer, negli anni quaranta lavora alacremente per decifrare "Enigma" la macchina che decriptò gli ordini inviati ai sommergibili tedeschi. Qualcuno paragona il suo successo all'impresa dei piloti della RAF durante la battaglia d'Inghilterra. Negl'anni cinquanta si occupa di intelligenza artificiale e propone il test di Turing per definire una macchina intelligente (guadare Blade Runner per maggiori informazioni).
Condannato per omossessualità, morirà suicida pochi anni dopo morsicando una mela intinta nel cianuro. Turing getta anche i fondamenti della matematica computazionale, cioè definisce cos'è computabile (calcolabile), ma va oltre, dimostra che un linguaggio di programmazione può risolvere qualunque problema computabile se supporta un certo numero di funzionalità. Per esempio le quattro operazioni, if-else, switch e poco altro. Quando un linguaggio rispetta tutte queste richieste (poche per la verità) si dice turing-completo.
I linguaggi di programmazione si sono evoluti molto in fretta ed hanno cominciato a aumentare il loro livello d'astrazione. Un computer non lascia niente al caso, tutto è deterministico, insomma è come un pedante ragioniere, il tipo di linguaggio che comprende è una lunga striscia di 0 e 1. Il programmatore, per quanto giudicato quadrato da artisti e letterati, gradisce un linguaggio più colloquiale, maggiormente espressivo.
Per questa ragione sono nati i compilatori, sono dei programmi che prendono un listato leggibile da umani un po' speciali e lo traduce in linguaggio capibile dalle macchine. Questa operazione si chiama "compilazione" ed avviene prima (e una volta sola) che il programma venga usato.
Verso la metà degl'anni novanta un linguaggio di programmazione molto noto (C++) viene arricchito con una nuova funzionalità di alto livello: i template. In sostanza si permette al programmatore di scrivere un programma generico che non dipende dai dati che sta trattando. Solo il cuore del programma è importante e non più il tipo di dato (intero, numero reale o variabile booleana). Il compito di sistemare le cose viene lasciato al compilatore che genererà del codice (di alto livello) che verrà poi ulteriormente trasformato in linguaggio macchina.
Quindi si è passati da una situazione:
codice di alto livello (scritto da umani) => linguaggio macchina
a:
codice generico (scritto da umani) => codice di alto livello (scritto dal compilatore) => linguaggio macchina
Il fatto che una macchina scriva del codice di alto livello è di per se un fatto interessante.
Ma lo è ancora di più se il linguaggio intermedio è anch'esso turing-completo. Poco dopo l'introduzione dei template in C++ un programmatore ha scritto un programma che falliva la compilazione (e quindi non creava nessun programma), ma che riportava nel messaggio d'errore la sequenza dei primi 10 numeri primi! Un nuovo linguaggio è apparso dal nulla, si posso scrivere programmi che si eseguono durante la compilazione.
Badate, non era intenzione di chi ha introdotto la funzionalità nel linguaggio ottere questo risultato; è semplicemente capitato. Alcuni linguaggi di programmazione sono diventati così complessi che contengono a loro volta altri linguaggi di livello inferiore.
Tutto è successo per caso! Turing ne sarebbe felice, forse.


