1. Parte 1
Gestione del codice
Linguaggi dinamici – A.A. 2009/2010
1
2. Introduzione
T I moderni linguaggi dinamici mettono a
disposizione dei meccanismi di manipolazione
avanzata del codice
T Tali meccanismi permettono di:
T identificare il tipo di un oggetto a tempo di
esecuzione
T modificare il codice del programma in
esecuzione
T intercettare e gestire gli errori a run time
Linguaggi dinamici – A.A. 2009/2010
2
4. Alcune definizioni
T Il metaprogramming è la scrittura di un
programma in grado di scrivere o manipolare
altri programmi o se stesso
T Più in generale, un metaprogramma effettua a
generale
tempo di esecuzioni operazioni che sarebbero,
in condizioni normali, effettuate a tempo di
normali
compilazione
T L'obiettivo d l
L' bi tti del metaprogramming è quello di
t i ll
produrre programmi in grado di adattarsi
dinamicamente ad una configurazione che
di i t d fi i h
cambia nel tempo, senza intervento umano
Linguaggi dinamici – A.A. 2009/2010
4
5. Alcune definizioni
T Metaprogramma: il prodotto dell'atto di
metaprogramming
T Metalinguaggio: linguaggio utilizzato per
scrivere il metaprogramma
T Linguaggio oggetto: il linguaggio del
programma manipolato
i l t
T Se il metalinguaggio ed il linguaggio di
programmazione coincidono, l'attività di
metaprogramming prende il nome di reflection
o introspection
Linguaggi dinamici – A.A. 2009/2010
5
6. Un primo esempio di metaprogramming
T Si consideri lo script di shell meta.sh
T Tale script crea (e scrive su disco) un
programma program.sh che stampa i numeri
da 1 a 1000
T L'esempio considerato è molto semplice, ed
introduce una forma di programmazione
generativa
T Genero codice in maniera esplicita
T Nelle forme più avanzate di metaprogramming,
p p g g,
non viene necessariamente generato codice
esplicito
p
Linguaggi dinamici – A.A. 2009/2010
6
8. Introduzione
T La forma di gran lunga più comune di
metaprogramming è quella in cui il programma
modifica il proprio comportamento a tempo di
esecu o e (reflection)
esecuzione ( e ect o )
T La reflection è implementata tramite un
insieme di meccanismi suppletivi al run time
del linguaggio
T Self-examination
Self examination (introspection)
T Self-modification
T Self-replication
Linguaggi dinamici – A.A. 2009/2010
8
9. Aspetti implementativi
T Un linguaggio che supporta la reflection deve
essere in grado di:
T identificare e modificare costrutti di codice
(blocchi, classi
(blocchi classi, metodi) a run time
T convertire una stringa contenente il nome
simbolico di un oggetto in un riferimento
all'oggetto a run time
T eseguire il codice contenuto in una stringa a
run time
T estendere le funzionalità offerte dal linguaggio
Linguaggi dinamici – A.A. 2009/2010
9
10. Type introspection
T La type introspection è la capacità di un
linguaggio (solitamente, orientato agli oggetti)
(solitamente
di determinare il tipo di un dato a tempo di
esecu o e
esecuzione
T La type introspection è spesso utilizzata per
implementare il polimorfismo
T Si individua il tipo di dato di un oggetto
T Si i di id la lista di metodi della classe di
individua l li t t di d ll l
appartenenza dell'oggetto
T Si esegue il metodo relativo
t d l ti
Linguaggi dinamici – A.A. 2009/2010
10
11. Individuazione dinamica di oggetti
T I linguaggi dinamici moderni hanno un
meccanismo di individuazione dinamica di
oggetti
T Si memorizza il nome dell oggetto in una
dell'oggetto
variabile di tipo stringa
T Si interpreta il contenuto della stringa come il
nome dell'oggetto desiderato (variabile, istanza
di una classe, metodo)
classe
Linguaggi dinamici – A.A. 2009/2010
11
12. Valutazione dinamica di espressioni
T I linguaggi dinamici moderni hanno un
meccanismo di esecuzione dinamica delle
espressioni
T Espressioni:
T Espressioni matematiche e logiche
T Blocchi di codice
Bl hi di
T Funzioni
T Si memorizza I'espressione che si vuole
valutare all'interno di una stringa
g
T Si intrepreta il contenuto della stringa, e si
ritorna il risultato
Linguaggi dinamici – A.A. 2009/2010
12
13. Valutazione dinamica di espressioni
T Vantaggi:
T È possibile costruire del codice polimorfo in
polimorfo,
grado di modificarsi ed adattarsi a tempo di
esecuzione
T Svantaggi:
T Se l
S le stringhe rappresentanti il codice non sono
i h i di
ben controllate, è possibile incorrere in seri
rischi di sicurezza
Linguaggi dinamici – A.A. 2009/2010
13
14. Estensione delle funzionalità
T I linguaggi dinamici moderni possono essere
estesi in diversi modi
T Estensione dell'API (run time)
T Concetto di modulo software
C tt d l ft
T Il programma diventa uno scheletro invocante
funzionalità importate
f i li à i
T Estensione dell'interprete (compile time)
T Scrittura moduli software per l'implementazione
di nuovi costrutti
T Esistono generatori di compilatori (Parrot) in
g
grado di semplificare il lavoro
p
Linguaggi dinamici – A.A. 2009/2010
14
16. Anomalie
T La stragrande maggioranza dei linguaggi
dinamici moderni prevede un meccanismo per
intercettare e gestire situazioni anomale a run
t e
time
T Classici esempi di anomalie a run time
T Puntatore ad una variabile nullo
T Indice array fuori limite
T Errore di I/O
T Divisione per 0
Linguaggi dinamici – A.A. 2009/2010
16
17. Eccezioni
T Il meccanismo standard di gestione delle
anomalie è quello delle eccezioni software
T Nato con il linguaggio SmallTalk
T Reso popolare dal linguaggio Java
R l d l li i J
T Presente nei linguaggi più popolari:
Perl, P th
P l Python, Ruby, C#
R b
Linguaggi dinamici – A.A. 2009/2010
17
18. Sollevamento delle eccezioni
T Il concetto di base è il seguente: ogni volta che
si presenta una anomalia, viene sollevata una
anomalia
eccezione
T Si interrompe il funzionamento del programma
T Viene eseguito codice di gestione (tipicamente,
per rilasciare le risorse ed uscire in maniera
pulita dal programma)
T Le eccezioni possono essere sollevate:
T In seguito ad anomalie provocate da istruzioni
T Manualmente, dal programmatore (parole chiavi
throw, raise)
Linguaggi dinamici – A.A. 2009/2010
18
19. Eccezioni: aspetti implementativi
T Il run time environment prevede la definizione
di una classe madre rappresentante la
generica eccezione software
T Tale classe contiene almeno:
T un identificatore dell'istanza di eccezione
T una rappresentazione dello stack al momento
i d ll k l
dell'anomalia
T Ciascuna anomalia a tempo di esecuzione può
essere vista come una sottoclasse particolare
della classe madre delle eccezioni
Linguaggi dinamici – A.A. 2009/2010
19
20. Costrutto Try-Catch-Finally
T Le anomalie generate a tempo di esecuzione
possono essere intercettate e gestite, senza
gestite
causare necessariamente un abort
T Si utilizza un costrutto molto popolare
popolare,
denominato try-catch-finally
T Nato
N t con il linguaggio SmallTalk
li i S llT lk
T Affermatosi con il linguaggio Java
T Presente nei linguaggi dinamici più popolari:
Perl, Python, Ruby, C#
T Se non si gestisce una eccezione, il run time
environment esegue un gestore di default
(stampa stack trace) ed esce
Linguaggi dinamici – A.A. 2009/2010
20
21. Costrutto Try-Catch-Finally
T La struttura generale del costrutto try-catch è
la seguente:
try {
<Blocco di codice>;
} catch (Eccezione e1) {
<Gestisci anomalia>;
}…{
catch (Eccezione en) {
<Gestisci anomalia>;
}…{
} finally {
<Codice eseguito alla fine del try-catch, sempre>;
}
Linguaggi dinamici – A.A. 2009/2010
21
22. Costrutto Try-Catch-Finally
T Viene eseguito il codice all'interno del blocco
try
T Se viene rilevata una anomalia, il run time
environment lancia una eccezione:
T individua la classe eccezione associata
all'anomalia
ll' li
T istanzia un oggetto di tale classe
T Individua il blocco catch relativo alla classe (o
alla prima superclasse compatibile) e lo esegue
T esegue il blocco finally
Linguaggi dinamici – A.A. 2009/2010
22
23. Costrutto Try-Except-Finally
T In python, il costrutto è molto simile a quello di
Java
try:
<Blocco di codice>;
except E
t Eccezione e1:
i
<Gestisci anomalia>;
…
except Eccezione en:
<Gestisci anomalia>;
except:
p
<Gestisci anomalia di una qualunque eccezione>;
else:
<Codice eseguito in assenza di eccezioni ;
Codice eccezioni>;
finally:
<Codice eseguito alla fine del try-except, sempre>;
Linguaggi dinamici – A.A. 2009/2010
23
24. Lancio manuale di eccezioni
T Oltre al costrutto try-catch-finally, viene fornito
anche un meccanismo per il lancio manuale di
eccezioni
T Parola chiave throw (o raise):
T Prende in ingresso un oggetto eccezione del
tipo specificato
T Lancia l'eccezione relativa
Linguaggi dinamici – A.A. 2009/2010
24
25. Modello Catch or Specify
T Alcuni linguaggi (Java, in particolare)
implementano un modello di tipo Catch or
Specify
T Ciascuna anomalia generata all interno di un
all'interno
metodo deve essere:
T gestita tramite un costrutto t
tit t it t tt try-catch-finally
t h fi ll
T dichiarata esplicitamente nella signature del
metodo (“rilanciata” - parola chiave th
t d (“ il i t ” l hi throws))
T Diversamente, il compilatore interrompe il
processo di compilazione con un errore
Linguaggi dinamici – A.A. 2009/2010
25
26. Parte 1
Gestione dinamica delle
funzioni
Linguaggi dinamici – A.A. 2009/2010
26
27. Introduzione
T I linguaggi dinamici moderni offrono
meccanismi per la definizioni di particolari
funzioni
T Funzioni anonime
T Closure
T Tali f
T li funzioni sono spesso utilizzate nel
i i tili t l
contesto di uno scheletro di codice generico,
per specializzare il comportamento del
i li t t d l
programma in funzione delle condizioni
operative
ti
Linguaggi dinamici – A.A. 2009/2010
27
28. Funzioni anonime
T Una funzione anonima è una funzione che non
è legata ad un nome e ad una signature
T Esempio: funzione di ordinamento
T Esegue sempre lo stesso algoritmo
E l t l it
T A seconda del tipo di dato, l'operatore di
confronto cambia
f bi
T Si può definire una funzione anonima come
operatore di confronto, e passarla come
argomento alla funzione di ordinamento
Linguaggi dinamici – A.A. 2009/2010
28
29. Funzioni anonime
T In Java, la definizione di una funzione anonima
richiede una nested class:
T ActionListener l = new ActionListener { public
void actionPerformed(ActionEvent e) {…}}
T In C# abbiamo i delegate:
T public delegate void Delegato(string s)
T static void Messaggio(string s) {
Console.WriteLine(s);}
Console WriteLine(s);}
T static void Main(string[] args)
T { Delegato dt = new DelegatoTest(Messaggio);
T dt ("Saluti"); }
Linguaggi dinamici – A.A. 2009/2010
29
30. Closure
T In topologia, una chiusura di un insieme è
l insieme
l’insieme stesso più tutti gli elementi
dell’ambiente circostante che servono a
rendere l’insieme c uso
e de e s e e chiuso
T Esempi:
T Dato l’intervallo (0 1) la sua chiusura è [0 1]
l intervallo (0,1), [0,1]
T Dato l’insieme dei punti interni di un rettangolo,
la sua chiusura è l’insieme più i punti del
l insieme
perimetro
Linguaggi dinamici – A.A. 2009/2010
30
31. Closure
S In informatica, la closure (chiusura) della
definizione di una funzione è data dal codice
della funzione più l’insieme dei dati
dell ambiente
dell’ambiente circostante che sono necessari
per completare la definizione della funzione
S P ti
Praticamente, la chiusura comprende:
t l hi d
S Non solo il codice della funzione
S Ma anche le variabili necessarie
S Attenzione! Il valore delle variabili viene
valutato alla chiamata
S Ogni istanza della funzione ha le sue
g
variabili
Linguaggi dinamici – A.A. 2009/2010
31
32. Closure
T Una closure è una funzione anonima, alla quale
è associato un insieme di parametri
T L'insieme dei parametri è assegnato non dal
programmatore (tramite una invocazione)
invocazione),
bensì da uno statement del programma (ad es.,
un iteratore)
T Tipicamente, lo closure sono disponibili se il
linguaggio supporta funzioni come fi t l
li i t f i i first-class
entities:
T Variabili che contengono (riferimenti a) funzioni
T Funzioni che restituiscono funzioni
Linguaggi dinamici – A.A. 2009/2010
32
33. Esempio di closure
function crea_contatore (int i)
{
var inizio = i; // variabile che fa parte della chiusura
return function { return inizio++; } ;
}
var da 5 = crea contatore(5);
da_5 crea_contatore(5);
var da_10 = crea_contatore(10);
print da_5() // 5
print da_5() // 6
print da_10() // 10
print da_5() // 7
print da 10()
da_10() // 11
Linguaggi dinamici – A.A. 2009/2010
33