Ciao, e benvenuto nella terza puntata della sessantottesima stagione. Abbiamo detto che un'esecuzione è una catena di stati, legati da un passo alla volta. Ma resta una domanda: chi decide qual è il passo? Cosa dice, in ogni situazione, quale sia la mossa successiva? La risposta sono le regole del gioco. Oggi vediamo come si scrivono, e perché sono il vero cuore di un linguaggio.
Partiamo dall'idea di regola, presa dai giochi da tavolo. Un buon regolamento non ti dice come andrà la partita: sarebbe impossibile, le partite sono infinite. Ti dice qualcosa di molto più furbo: data una certa situazione, ecco cosa puoi fare. Se il pezzo è questo e si trova qui, allora può muoversi così. Sono regole locali, che parlano solo di un pezzetto di situazione alla volta. Eppure, applicandole una dopo l'altra, coprono ogni partita possibile, anche quelle mai giocate prima. Le regole di esecuzione di un linguaggio funzionano nello stesso identico modo.
Vediamo la forma di una regola, perché è più semplice di quanto la parola suggerisca. Una regola dice: se ti trovi in una situazione fatta così, allora il passo da fare è quest'altro. Una condizione, e la mossa che ne segue. Il linguaggio è definito da un insieme di queste regole, una per ogni tipo di situazione che può capitare. Come sommare due numeri, come seguire una condizione, come ripetere un ciclo, come chiamare una funzione, come leggere o scrivere una variabile. Metti insieme tutte queste regolette locali, e hai definito, senza ambiguità, come si esegue qualsiasi programma di quel linguaggio.
Voglio mostrarti il gesto centrale con un esempio, quello di valutare un'espressione. Immagina un calcolo un po' annidato, con più operazioni dentro. Come si esegue? Non tutto in una volta. Trovi il pezzo più interno che è pronto per essere calcolato, quello che ha già tutti i suoi ingredienti. Lo risolvi, e lo sostituisci col suo risultato. Ora l'espressione è un po' più semplice. Cerchi di nuovo il pezzo pronto, lo risolvi, lo sostituisci. E vai avanti così, semplificando un morso alla volta, finché non resta un solo valore. Eseguire, molto spesso, è proprio questo: ridurre, un pezzo alla volta, fino a una forma finita che non si può più ridurre.
Nota una proprietà importante, che riguarda quanta libertà lasciano le regole. In molti linguaggi, in ogni situazione, la regola che si applica è una sola: da lì c'è un unico passo possibile, e quindi un unico modo in cui l'esecuzione può procedere. Si dice che è deterministico: stesso punto di partenza, stesso film, sempre. È una proprietà preziosa, perché rende il comportamento prevedibile e ripetibile. Ci sono casi in cui le regole lasciano invece più di una mossa possibile, e allora le cose si complicano: ma di questo parleremo più avanti, perché merita una puntata sua.
C'è un'immagine che rende viva tutta questa faccenda: pensa a un arbitro con il regolamento in mano. L'arbitro non conosce in anticipo come finirà la partita. Fa una cosa sola, instancabilmente: guarda la situazione sul campo, cerca nel regolamento la regola che vi si applica, e dichiara qual è la mossa consentita. Poi la situazione cambia, e ricomincia. Un interprete di un linguaggio è esattamente quell'arbitro: ha in mano le regole di esecuzione, guarda lo stato attuale, trova la regola giusta, e compie il passo. Poi di nuovo, e di nuovo, fino alla fine.
Voglio farti vedere perché questo ti serve, e non è teoria astratta. Quando due persone discutono su cosa faccia un pezzo di codice ambiguo, in fondo stanno discutendo su quale regola si applichi. Quando impari un linguaggio nuovo e ti sorprende come si comporta, è perché le sue regole sono diverse da quelle che avevi in testa. E quando un tuo programma fa una cosa che non capisci, spesso il problema è che tu stavi applicando mentalmente una regola, e il linguaggio ne applicava un'altra. Conoscere le vere regole del gioco, e non quelle che immagini, è metà del mestiere.
Resta la lezione di fondo, e vale ben oltre i linguaggi. I sistemi complessi non si capiscono memorizzando tutti i loro comportamenti possibili: sono troppi, spesso infiniti. Si capiscono imparando le poche regole locali che li governano, quelle che dicono, in ogni situazione, cosa succede dopo. Poche regole semplici, applicate senza sosta, generano tutta la ricchezza del comportamento. Trova le regole, e avrai in mano il sistema, molto più che memorizzandone i risultati.
Per oggi ci fermiamo qui. Abbiamo visto chi decide i passi: le regole del gioco. Non descrivono come andrà la partita, ma dicono, data una situazione, qual è la mossa consentita: una condizione e la mossa che ne segue, tante regolette locali che insieme coprono ogni programma possibile. Il gesto centrale, valutare un'espressione, è ridurre un pezzo alla volta finché resta un solo valore. Quando da ogni situazione c'è un'unica mossa, l'esecuzione è deterministica: stesso inizio, stesso film. Come un arbitro che guarda il campo, cerca la regola e dichiara la mossa: un interprete fa proprio questo. La lezione: i sistemi complessi si capiscono imparando le poche regole locali che li governano, non memorizzandone i comportamenti. Nella prossima puntata: piccoli passi, grandi passi. Nelle note trovi qualche spunto. Se ti è utile, condividila. Grazie per l'ascolto, e ci sentiamo alla prossima.