Giuseppe Maggiore, Ph.D. Student, MSP
Universitá Ca’ Foscari – Venezia
Problemi aperti nella programmazione
Definire la gestione di eccezioni. Costruire un parser. Accumulare delle informazioni di stato ad ogni riga di una computazione. Definire un sistema concorrente. Maneggiare collezioni in modo dichiarativo á la LINQ. Cosa hanno in comune queste applicazioni? Che ogni riga del codice scritto deve eseguire delle operazioni relativamente ripetitive. Tramite le monadi é possibile realizzare un wrapper che viene applicato ad ogni riga del nostro codice in modo da nascondere completamente al programmatore cosa sta accadendo “dietro” le quinte; le operazioni nascoste possono creare thread, gestire collezioni, costruire e manipolare GUI o eseguire complessi calcoli matematici, il tutto senza che il programmatore debba muovere un dito.
Cosa sono le monadi?
Le monadi sono un costrutto sintattico (che in linguaggi come Haskell o F# viene “zuccherato” in modo da renderlo piú piacevole da vedere e intuitivo da usare) tramite cui possiamo fare si che ogni riga di codice del nostro programma svolga anche una serie di operazioni nascoste; in tal modo possiamo crearci dei mini-linguaggi di altissimo livello in cui le istruzioni sono completamente definite da noi: siccome la gestione della sintassi é giá fatta dal linguaggio ospite, peró, non abbiamo nessuno dei problemi associati alla costruzione di un vero linguaggio. Inoltre siamo comunque ospitati dall’ambiente di esecuzione del linguaggio ospite, quindi ad esempio nel caso di F# il nostro mini-linguaggio di altissimo livello puó poggiarsi a qualsiasi funzionalitá offerta dal .Net.
Ok, bello, ma io cosa posso farci?
L’elenco di cose fattibili con le monadi é lunghissimo. L’idea di base é che una monade rende facile nascondere una logica sottostante che viene ripetuta spesso. Ad esempio possiamo creare una monade per la gestione dell’iterazione di liste, in cui parliamo solo dell’elemento corrente di una serie di liste:
list{
let! x = [1..10]
let! y = [1..10]
if x > y then return (x,y)
}
In cui costruiamo il prodotto cartesiano delle liste e manteniamo solo le coppie in cui il primo elemento é maggiore del secondo.
Possiamo costruire una monade di gestione di messaggi asincroni, in cui scriviamo
msg{
let! x = receive_from ip
do! send_to (x+1) ip
}
In cui riceviamo e mandiamo dei messaggi ad un altro host senza menzionare tempi di attesa o errore o creazione di canali di comunicazione.
Infine (per il resto vi rimando ai webcast) é possibile semplificare un vastissimo insieme di operazioni, praticamente quasi qualsiasi cosa in cui é possibile individuare una logica ripetuta sottostante in contesti in cui la libertá di programmare di chi usa la logica ripetuta deve essere mantenuta. Insomma, le monadi sono lo strumento ideale per il programmatore che vuole costruire delle “über-macro” J per il proprio codice…
Webcast(s)
Monade per la gestione degli errori:
Monade per l’iterazione e composizione di collezioni:
Monade per la creazione di un linguaggio specifico di dominio (DSL):
Monade per la creazione dichiarativa di GUI (simile a XAML in WPF):