steve's

Ambiguità felice dei linguaggi

Feb
23

C’è una barzelletta che gira da tempo sui programmatori, esseri inadatti al mondo reale. Dice così:

La mamma dice a Pierino: vai al mercato e compra 2 litri di latte. Se ci sono le uova, comprane 6.
Pierino va e torna con 6 litri di latte.
La mamma: Perché hai comprato 6 litri di latte?
Pierino: Perché c’erano le uova.

Finite le risate per la risposta di Pierino (che immaginiamo essere il risultato di una specie di programma: IF ci sono le uova THEN comprane 6), ci accorgiamo che il problema è in quella particella “ne”, che è un riferimento pronominale. Di quelle cose che abbiamo detto prima. Un link, una URL relativa.
In Italiano, di solito, si riferisce all’ultimo sostantivo utilizzato. Quando ce ne sono più di uno (di che? di sostantivi) di solito con un minimo di interpretazione si capisce a quale ci si riferisce.
Se la mamma avesse detto:
[…] Se c’è lo zucchero, comprane 6 litri.
un parlante Italiano avrebbe capito che il riferimento era al latte, perché sa che lo zucchero non si vende a litri.

E’ uno degli aspetti tipici del linguaggio naturale: un riferimento generico può essere comodo in molti casi, ma può creare dubbi in altri. Dubbi che vanno risolti con delle ipotesi, oppure nell’interazione (“Scusa, mamma: 6 di cosa?”).

Si dice che i linguaggi di programmazione, essendo “formali”, non soffrono di queste malattie, anzi sono stati costruiti apposto per esserne immuni. La barzelletta prende in giro proprio questa ottusità dei computer, dei linguaggi, dei programmi. I computer non interpretano i programmi, ma li eseguono rigidamente. Per cui niente libertà, niente interpretazione, niente poesia, solo correttezza e efficienza.

Ma siamo proprio sicuri che sia così? Facciamo un gioco: traduciamo la storiella in un linguaggio molto usato per il web, ovvero PHP (tranquilli: il discorso può essere seguito da chiunque, anche senza nessuna competenza informatica).

$lista = Array (
 latte => 1,
 uova => 6
 );

In questo frammento di codice sorgente viene creato un dizionario ($lista), cioè una set di dati organizzati per coppie chiave/valore (latte=1, uova=6).
Ci si mettono dentro le informazioni e poi si possono estrarre quando servono.
Scrivendo così:

 print_r($lista);

possiamo vedere cosa c’è dentro $lista:

Array
(
    [uova] => 6
    [latte] => 1
)

Oppure, volendo andare più in dettaglio:

 
print_r($lista[latte]);

cioè: scrivi sullo schermo il valore della chiave “latte” nell’array $lista.
Che è, ovviamente, 1.

Se però guardiamo cosa succede dietro le quinte, ci accorgiamo che l’interprete ha segnalato due errori veniali:

PHP Notice: Use of undefined constant latte - assumed 'latte'
PHP Notice: Use of undefined constant uova - assumed 'uova'

E’ un nostro errore di scrittura: le chiavi sono state scritte come se fossero costanti (cioè senza le virgolette che invece accompagnano le stringhe di caratteri), ma non esiste nessuna costante che si chiama latte, né uova. Ma cosa ha fatto l’interprete PHP, oltre a segnalare l’errore? Ha fatto un’illazione, cioè ha supposto che si volesse scrivere:

'latte' =>1,
'uova' => 6

che sembra in effetti l’interpretazione più ragionevole.

Se siamo bravi programmatori e programmatrici, una volta letta la segnalazione correggiamo il codice, e tutto fila liscio.
Anzi, per essere ancora più precisini, creiamo una costante (visto che ci era stato chiesto), ma le diamo un valore un po’ bizzarro:

define('latte',uova);

Cioè: abbiamo definito una costante che ha come nome “latte”, ma come valore “uova”.
Vi sembra confondente? Ma il linguaggi di programmazione sono precisi, no? Quindi nessun problema: da un lato la costante, dall’altro la chiave.
E infatti, se avessimo lasciato le cose come stavano, non ci sarebbero stati problemi. Ma noi abbiamo voluto essere rigorosi e abbiamo creato la costante E messo gli apici intorno alle chiavi.
Ora se chiediamo:

print_r(latte);

(ovvero: qual è il valore della costante “latte”?), otteniamo la stringa “uova”, come prevedibile; mentre se chiediamo di nuovo:

print_r($lista[latte]);

il risultato non è né “uova”, né 1 ma …  6 !
Il che naturalmente ha una sua logica. Si potrebbe dire che l’interprete ha usato il riferimento pronominale nella nostra richiesta, e ha interpretato la chiave dell’array $lista[latte] come la costante “latte” che era stata definita prima. Ma non è quello che volevamo dire. Insomma, dal nostro punto di vista,  si confonde e restituisce 6, cioè interpreta il codice come se avessimo scritto:

print_r($lista[uova]);

Proprio come Pierino.

Ora cambiamo l’ordine delle chiavi:

$lista = Array (
 'uova' => 6,
 'latte' => 1
 );

e chiediamo di nuovo:

print_r($lista[latte]);

Dovrebbe essere uguale a prima, no?
Eh no, adesso il valore restituito è tornato ad essere 1!
Meglio, dite? Insomma… se provate a scrivere:

print_r($lista);

vi accorgete del pasticcio:

Array
(
    [uova] => 1
)

La chiave latte è stata sostituita da uova (con valore 1) e la chiave uova, che avevamo inserito con valore 6, è stata cancellata.

Certo PHP non è un modello di precisione, per un linguaggio di programmazione. Ma insomma: anche un linguaggio di programmazione è soggetto ad una forma di ambiguità referenziale. E questo dipende, come abbiamo visto, dall’ordine in cui vengono inserite le informazioni nel testo.
Come in una qualsiasi lingua naturale…

Ancora sugli algoritmi

Feb
07

Tornano di moda, arrivano sulle prime pagine dei giornali, sono oggetto di approfondimenti (come questo sul Sole 24 ore di qualche mese fa) e di libri (come questo di Mario Pireddu appena uscito). Quanto sarebbe stato felice il vecchio Abū Jaʿfar Muḥammad ibn Mūsā al-Khwārizmī, matematico, geografo, astronomo persiano del IX secolo, autore di un libro famosissimo, tradotto in Latino col titolo di “Algoritmi de numero Indorum” (generando un po’ di confusione tra il nome dell’autore e l’argomento).
Però gli algoritmi di oggi non hanno a che fare con l’algebra ma con l’informatica: si tratta della definizione di una procedura in passi elementari, così semplice che la può eseguire anche una macchina. Ci sono esempi famosissimi: l’algoritmo detto “Crivello di Eratostene” per trovare tuttii numeri primi, oppure il Bubblesort per ordinare una lista.

Gli algoritmi sono quella cosa che, se espressa in un linguaggio di programmazione, dà origine ad un programma. Per esempio, questo algoritmo:

  1. Ripeti per sempre l’istruzione seguente
  2. Scrivi “CIAO” sullo schermo

potrebbe essere rappresentato così:

 

 

 

e potrebbe essere scritto in BASIC così:

10 PRINT "CIAO"
20 GOTO 10

Ma nell’uso attuale (almeno di questi ultimi dieci anni, da quando in Italia è uscito “L’algoritmo al potere. Vita quotidiana al tempo di Google” di Francesco Antinucci, Laterza, 2009) algoritmo ha un’accezione ancora più ristretta. Sono chiamati così quei programmi che:
a) raccolgono dei dati relativi ai comportamenti delle persone, tipicamente online
b) li  utilizzano per costruire un profilo delle stesse persone
c) usano il profilo per fare, o supportare, delle scelte

Ci sono vari punti oscuri: la liceità della raccolta dei dati all’insaputa dell’utente, la maniera in cui viene costruito il profilo e soprattutto l’utilizzo del profilo per scopi illeciti (per esempio, aumentare un premio assicurativo o rifiutare una candidatura per un posto di lavoro).

Ora non entriamo nella discussione sui guadagni reciproci dell’utente e del fornitore di servizi, sulla necessità di policy di trasparenza e cancellazione, sulla possibilità reale di non utilizzare quei servizi. Probabilmente il tema si incrocia con quello del ritorno in auge dell’Intelligenza Artificiale, dei robot, dei big data, del machine learning, in un allarme generale sull’imminente presa del potere da parte delle macchine. Algoritmo è solo un modo diverso di dire “automatismo fuori dal controllo umano”.  Ma allora è proprio l’uso del termine algoritmo che è fuorviante.

Qualsiasi programma – dal client di posta elettronica al foglio di calcolo – contiene migliaia di algoritmi, o meglio può essere letto attraverso la lente dell’algoritmo che implementa, esattamente come un proposizione in una lingua naturale può essere letta attraverso le strutture sintattiche di quella lingua. Gli algoritmi non abitano un loro mondo a parte, non hanno uno statuto speciale. Per essere spiegati, raccontati, analizzati, devono essere espressi anche loro in qualche linguaggio (anche con fumetti, come in questo manuale introduttivo). E’ vero che per mostrare che due programmi, magari scritti in due linguaggi diversi, fanno la stessa cosa nello stesso modo si dice che implementano lo stesso algoritmo e si descrive questa parte comune con un terzo linguaggio  più generale degli altri due. Linguaggio che può essere più o meno formale . Ma insomma, gli algoritmi non sono l’anima dei programmi, non esistono prima del programma o in un universo separato, ma sono solo un modo per parlarne da un certo punto di vista (quello della correttezza, dell’efficienza). In un articolo di qualche tempo fa mi interrogavo sul senso di questa visione platonica, che è talmente presente nella nostra cultura che è difficile esserne coscienti.

E quindi parlare di algoritmo invece di programma è una raffinatezza di cui francamente non capisco il vantaggio. E’ come dire: non metto sotto accusa quel libro, ma le idee che ci sono dentro. Le quali idee però (ammesso che preesistessero alla stesura del libro) sono state estratte e  riassunte da qualcuno dopo aver letto il libro.

Peraltro, nei casi sopra citati, il punto non è l’esistenza di un algoritmo (è ovvio che ci sia, altrimenti non ci sarebbe nemmeno il programma) e nemmeno la natura dell’algoritmo, ma i pesi che gli vengono forniti; pesi stabili da persone umane, non da macchine. Per esempio, il fatto che voi leggiate questo articolo  potrebbe avere un peso negativo, o comunque legato alla reputazione del suo autore, nella costruzione e aggiornamento del vostro profilo da qualche parte. Questo è deciso da qualcuno, non da un algoritmo, il quale si limita a comporre il profilo utilizzando i pesi forniti e applicandoli.

Parlare di algoritmi cattivi ha senso tanto quanto parlare di strutture sintattiche malvage. Gli algortmi possono essere valutati, ma in termini di efficienza, scalabilità, robustezza, magari eleganza. Prendersela con loro per il cattivo comportamento dei consigli di amministrazione delle società che offrono serivizi gratuiti online – in cambio dell’accesso libero a dati che poi rivendono – mi sembra un po’ ingiusto nei confronti del vecchio al-Khwārizmī e francamente anche dell’informatica.

Poeti, navigatori, santi e cuochi: cosa insegna la linguistica computazionale al coding?

Gen
31

L’incontro tra informatica e letteratura avviene ufficialmente, almeno in Italia, quando nel 1949 Padre Busa SJ si dedica all’immane compito di compilare un Index Thomisticus, cioè un repertorio di tutti i termini utilizzati dall’Aquinate nelle sue opere. Per farlo, chiede il supporto dell’IBM (parlando con il suo fondatore, Watson) e inizia un lavoro di lemmatizzazione durato trent’anni. Dopo la versione cartacea (1980) e quella su cdrom (1989), nel 2005 nasce la versione web (http://www.corpusthomisticum.org/it/index.age).

La linguistica computazionale si presenta così con un aria seriosa, doppiamente sostenuta dall’oggetto (il testo classico) e lo strumento (il programma di lemmatizzazione e ricerca), per non parlare dello scopo scientifico.

Ma ci sono stati altri incontri meno nobili, come quello tra il libro cartaceo Cent Mille Miliards de Poèms di Raymond Queneau e il web. Per chi non avesse avuto la fortuna di sfogliare quel meraviglioso oggetto, si tratta di un libro pubblicato nel 1961 che raccoglie dieci sonetti di quattordici versi ognuno. La peculiarità che lo rende unico è la pagina è tagliata in orizzontale in modo da rendere ogni verso un oggetto autonomo; è possibile così leggere (e costruire con la mente) un sonetto costituito, poniamo, dal primo verso della prima pagina, il secondo dalla decima, il terzo dalla quinta, e così via. Le possibilità totali sono 1014, cioè appunto 100.000.000.000.000. Di questa macchina per generare sonetti ne esistono varie versioni consultabili su web, come per esempio questa: http://www.growndodo.com/wordplay/oulipo/10%5e14sonnets.html

Queneau realizza (cioè “dimostra la possibilità”) di qualcosa che nel cielo delle invenzioni letterarie era ben nota. A partire per lo meno dalla macchina creata dagli scienziati dell’Accademia di Laputa:

La superficie risultava di vari pezzetti di legno, grossi press’a poco come dadi, alcuni di maggiore dimensione degli altri. Erano tutti congiunti da esili fili di ferro. Incollata sopra le quattro facce dei pezzetti di legno era della carta, e su questa si trovavano scritte tutte le parole della loro lingua, coniugate nei diversi modi e tempi e declinate nei vari casi, ma senza ordine veruno. Il professore m’invitò a prestare attenzione, ché appunto s’accingeva a mettere in moto la macchina. Ciascun discepolo prese, al cenno del maestro, un manico di ferro (ce n’erano quaranta fissati intorno agli orli della macchina) e d’un tratto lo fece girare. Naturalmente la disposizione delle parole cambiò in tutto e per tutto. Il maestro ordinò allora a trentasei scolari di leggere pian pianino i vari righi così come apparivano sulla macchina; e quando quelli trovavano tre o quattro parole unite insieme che potevano far parte d’una sentenza, le dettavano ai quattro rimanenti discepoli che fungevano da scrivani (Jonathan Swift, I viaggi di Gulliver, Traduzione di Carlo Formichi, a cura di Masolino d’Amico, Mondadori, Milano, 1982, p. 393).

passando, naturalmente, per Borges, Levi, Landolfi e Dahl. Molti altri esempi sono citati in questa trascrizione di una bellissima conferenza del 2015 tenuta da Paolo Albani (a meno che non sia anche questo un testo generato automaticamente) che potete leggere qui: http://www.paoloalbani.it/Letteraturacombinatoria.pdf.

Cosa mostra davvero questo strano artefatto, nella versione cartacea come in quella digitale? Che la letteratura (e in particolare la poesia) non è tutta intuizione ed espressione libera. Che il gioco tra sistema e creatività, tra regola ed eccezione, non è proprio così chiuso come sembra. La poesia, in particolare, nasce proprio dal vincolo (tematico, formale), come orizzonte e come sfida. Non lo dico io, lo dice Calvino: la letteratura è

“un’ostinata serie di tentativi di far stare una parola dietro l’altra seguendo certe regole definite, o più spesso regole non definite né definibili ma estrapolabili da una serie di esempi o protocolli, o regole che ci siamo inventate per l’occasione cioè che abbiamo derivato da altre regole seguite da altri” (Cibernetica e fantasmi. Appunti sulla narrativa come processo combinatorio, in: Una pietra sopra. Discorsi di letteratura e società, Einaudi, Torino, 1980, pp. 164).

E cosa fa il poeta quando crea, se non andare a pescare nella sua memoria linguistica e scegliere combinazioni di parole, vincolate da regole precise (come il metro o la rima)? Certo, la scelta è anche governata dal significato – in maniera difficile da precisare. Il poeta parte con l’idea da esprimere e cerca le parole più adatte? Oppure si lascia guidare dalle parole stesse, sfruttando somiglianze fonetiche, rimandi per analogia o opposizioni? O ancora, più probabilmente, attua un misto delle due strategie? Insomma: come si scrive, praticamente, una poesia?

E di qui l’idea di proporre delle attività didattiche di coding intorno ai temi della forma e della variazione, delle categorie, dell’accettabilità. In un periodo in cui il machine learning sembra riproporre il vecchio mito dell’intelligenza artificiale, viene voglia di ragionare intorno ai processi creativi anche utilizzando paradossi, e di provare a costruire un automa in grado, se non di scrivere poesie originali (come questo: http://thinkzone.wlonk.com/PoemGen/PoemGen.htm, o quest’altro fatto addirittura in Scratch che lavora per sottrazione da una poesia di Walt Whitman: https://scratch.mit.edu/projects/12331423/) almeno di inventare ricette sempre nuove, che tutto sommato sono sempre forme di testo vincolate, come questa: http://www.lynxlab.com/staff/steve/public/ricette.

Per restare nel dominio letterario, due modesti esempi di macchine figlie di quella di Queneau (ma che pescano nel testo di due classici sempreverdi come l’Inferno di Dante Alighieri e l’Orlando Furioso di Ludovico Ariosto) li trovate qui http://www.lynxlab.com/staff/steve/public/inferno e qui http://www.lynxlab.com/staff/steve/public/orlando. Oltre a Queneau, questi due oggetti digitali si ispirano più precisamente a “Il centunesimo canto. Philologica dantesca“di Luca Chiti, che è un meraviglioso esempio di centone umoristico che “crea” un intero canto giustapponendo versi esistenti ma dandogli un senso completamente nuovo. Per realizzarli, ho dovuto affrontare problemi letterari, come la definizione di rima, di struttura metrica, di novità e ripetizione (oltre che qualche problema informatico, come il loop infinito o la conversione dei caratteri in UTF-8). Non ho seguito alla lettera le indicazioni di Nanni Balestrini, ma ci sono andato vicino. Ed ecco apparire terzine più o meno improbabili come la seguente:

Parlando cose che ‘l tacere è bello
rispuosemi: «non omo, omo già fui
venimmo al piè d’un nobile castello

o come questa:

Nel nome che sonò la voce sola
poscia vid’io mille visi cagnazzi
cosí vidi adunar la bella scola

Una valutazione estetica del risultato? Non è l’obiettivo, anche se può essere divertente provare e riprovare, fino a far emergere dei frammenti di senso che possono essere anche divertenti. Ma quelle che mi paiono importanti, come sempre, sono le domande che emergono ogni volta che si prova a realizzare un modello funzionante di una teoria: come si riconosce una rima? Come si produce una struttura metrica? Come si ottiene un testo casuale sempre diverso? Come si riconosce che il testo non è stato scritto da un poeta umano?

Mi sembrano tutte domande legittime da porsi in una classe che studia letteratura: portano con sé riflessioni e discussioni che integrano, anche se non sostituiscono, l’apprendimento di nomi di forme di testo come “trimetro scazonte” o “endecasillabo sciolto” o di opere particolari.

E ancora una volta mostrano come la costruzione reale di un programma possa essere un’attività didattica sensata al di là di ogni mitologia computazionale.

 

Un elefante, sei ciechi e quattro saggi

Gen
12