1. Parte 1
Tipizzazione dei dati
p
Linguaggi dinamici – A.A. 2009/2010
1
2. Entità di un programma
T In un programma, ad ogni entità è associato:
T Nome, identificatore unico nel programma (o in
una porzione)
T Tipo, per indicare l insieme dei valori e delle
l'insieme
operazioni
T Valore, tra quelli ammessi dal tipo
T Indirizzo, riferimento alla memoria che la
contiene
T Tempo di vita, durata di esistenza nel
programma
T Visibilità (scope) del nome nel programma
Linguaggi dinamici – A.A. 2009/2010
2
3. Definizione di tipizzazione
T Ciascun linguaggio di programmazione è
dotato di un sistema per la tipizzazione dei dati
T Tipizzazione dei dati: meccanismo trattabile di
analisi sintattica che classifica una porzione
del codice in base ai valori che essa calcola
T Molto iù i f
M lt più informalmente: il compilatore cerca
l t il t
di capire di che categoria (o tipo) è un valore
prodotto (type checking)
d tt (t h ki )
T Il tipo caratterizza le operazioni che si possono
compiere sul valore prodotto, i suoi limiti, la
sua “precisione”
Linguaggi dinamici – A.A. 2009/2010
3
4. Porzioni di codice
T A quali porzioni di codice viene solitamente
associato un tipo?
T Valori in memoria (costanti)
T Variabili
V i bili semplici
li i
T Variabili complesse (strutture dati)
T Espressioni
T L'associazione di un tipo di dati ad una
p
porzione di codice informa il compilatore,
l'interprete ed il programmatore su come tale
p p g
porzione di codice possa essere utilizzata
Linguaggi dinamici – A.A. 2009/2010
4
5. Tipi di dato
T Quali sono i tipi che si possono associare alle
porzioni di codice?
T I tipi associabili sono classificabili in due
distinte categorie
T Tipi di dato semplici: caratterizzano un dato
primitivo, su cui si possono effettuare
i iti i i ff tt
operazioni “semplici” (numero, caratteri,
booleani)
T Tipi di dato complessi: caratterizzano un dato
composto da più dati semplici, su cui si
semplici
possono effettuare operazioni “complesse”
(stringhe,
(stringhe struttura dati, classe)
dati
Linguaggi dinamici – A.A. 2009/2010
5
6. Tipi di dato
T Esempi di tipi di dato semplici
T Int, Integer Float double Char String
Int Integer, Float, double, Char, String, Boolean
T Puntatori
T Esempi di tipi di dato complessi
T Struct, union
T Class
Linguaggi dinamici – A.A. 2009/2010
6
7. Obiettivi della tipizzazione:
Safety
T L'uso dei tipi permette al compilatore di
scoprire il più presto possibile (a livello di
compilazione) codice privo di senso/illecito
T Si consideri l espressione 3 / “Hi World”
l'espressione Hi World
T Tale espressione (che non ha alcun senso) è
scomponibile nel seguente modo:
ibil l t d
T Operando 1: tipo semplice intero 3
T Operando 2: tipo stringa “Hi World”
T Operatore: divisione /
p
T L'operatore divisione non prevede le stringhe!
T Il compilatore emette un syntax error
Linguaggi dinamici – A.A. 2009/2010
7
8. Obiettivi della tipizzazione:
Safety
T Ma attenzione!
T Si consideri l'espressione ‘a’ / 5
’
T Anche in questo caso non avrebbe senso
dividere un carattere, ma il C considera questa
di id tt id t
espressione come ASCII(‘a’) / 5
T Si consideri l'espressione 70 / “2”
T È sempre una operazione che potrebbe non
avere senso, ma un compilatore/interprete
potrebbe considerarla come 70 / 2 convertendo
la t i
l stringa “2” nell’intero che rappresenta
ll’i t h t
T Naturalmente se si ha una generica variabile
stringa non è detto che rappresenti un numero
Linguaggi dinamici – A.A. 2009/2010
8
9. Obiettivi della tipizzazione:
Ottimizzazione
T Le operazioni di type checking, se eseguite in
uno stadio iniziale (compilazione) possono
fornire informazioni utilissime
T Ad esempio, se ad una analisi sintattica segue
esempio
l'immediato type checking, si può scoprire che
una variabile è un puntatore
T Se tale indirizzo è allineato (su architetture a
32 bit un multiplo di 4 byte), l'accesso in
bit, lti l b t ) l' i
memoria è molto più rapido
T Sapendo ciò in anticipo, il compilatore può
utilizzare istruzioni efficienti per accedere al
dato
Linguaggi dinamici – A.A. 2009/2010
9
10. Obiettivi della tipizzazione:
Documentazione
T Nei sistemi di tipizzazione più espressivi, i tipi
possono servire quale utile fonte di
documentazione del codice
T Il tipo di dato illustra la natura di una variabile,
variabile
ed in ultima analisi l'intento del programmatore
T Ad esempio, un timestamp (marcatore
i ti t ( t
temporale) è, solitamente, un intero a 32/64 bit
T Dal punto di vista della comprensione del
codice, è ben diverso leggere int a = 32;
oppure timestamp a=32;
T Definizione di nuovi tipi di dato (typedef in C)
p ( yp )
per aumentare l'espressività del linguaggio
Linguaggi dinamici – A.A. 2009/2010
10
11. Obiettivi della tipizzazione:
Astrazione
T Il meccanismo dei tipi permette di produrre
programmi ad un livello di astrazione più alto
di quello nativo della macchina (bit, byte)
T Ad esempio, una stringa di caratteri può
esempio
essere vista a basso livello come una
sequenza di byte (o di bit)
T Per l'essere umano, è molto più intuitivo
pensare ad una stringa come ad una
d ti d
concatenazione di caratteri
T Java: operatore + applicato alle stringhe
Linguaggi dinamici – A.A. 2009/2010
11
12. Obiettivi della tipizzazione:
Modularità
T L'uso appropriato dei tipi di dato costituisce
uno strumento semplice e robusto per definire
interfacce di programmazione (API)
T Le funzionalità di una data API sono descritte
dalle signature (i prototipi) delle funzioni
pubbliche che la compongono
T Leggendo tali signature, il programmatore
(esperto) si fa immediatamente un'idea di cosa
( t ) if i di t t 'id
può (o non può) fare
Linguaggi dinamici – A.A. 2009/2010
12
13. Un avvertimento
T Attenzione! I meccanismi che garantiscono le
proprietà ora viste non sono una panacea!
T Tali proprietà aiutano a catturare errori di
natura per lo più sintattica
T Il meccanismo di tipizzazione (ma anche il
compilatore, o l'interprete) non può nulla
il t l'i t t ) ò ll
contro la programmazione sloppy (sciatta) che
produce errori di natura semantica
d i t ti
T Un ciclo non viene mai terminato
T Il flusso del programma è sballato
T Una risorsa acquisita non viene mai rilasciata
q
Linguaggi dinamici – A.A. 2009/2010
13
14. Type checking
T L'operazione di type checking ha l'obiettivo di
verificare e di stabilire il tipo di dato associato
ad una determinata porzione di codice
T Tale operazione può avvenire:
T a tempo di compilazione (compile time)
T a tempo di esecuzione (run time)
i ( i )
T Tale operazione può:
T Garantire la non perdita di informazione durante
le operazioni di conversione
T Non garantire la perdita di informazione durante
le operazioni di conversione
p
Linguaggi dinamici – A.A. 2009/2010
14
15. Type checking statico
T Un linguaggio di programmazione utilizza un
meccanismo di type checking statico se le
operazioni di type checking sono eseguite solo
a tempo d compilazione
te po di co p a o e
T Linguaggi a type checking statico:
T C, C++, C#, Java, Fortran,
C C++ C# Java Fortran Pascal
T Il type checking statico:
T è inteso come una forma primitiva di verifica di
un programma
T permette di individuare parecchi errori con
largo anticipo (early)
T permette una migliore ottimizzazione del codice
Linguaggi dinamici – A.A. 2009/2010
15
16. Type checking statico
T Osservazioni:
T i tipi delle espressioni sono determinati durante
il processo di compilazione
T un compilatore non può sapere quali dati avrà
il t ò li d ti à
in ingresso/genererà il programma eseguibile
T Il t
type checking statico è conservativo
h ki t ti ti
T Esempio: if ('A' == 65) printf(“okn”);
T L'if è vero, tuttavia il solo meccanismo di
tipizzazione, senza un meccanismo di
p ,
conversione dei tipi, non potrebbe stabilire se
'A' == 65, e dovrebbe fallire
,
Linguaggi dinamici – A.A. 2009/2010
16
17. Type checking dinamico
T Un linguaggio di programmazione utilizza un
meccanismo di type checking dinamico se la
maggior parte delle operazioni di type
c ec g sono eseguite tempo d esecu o e
checking so o esegu te a te po di esecuzione
T Linguaggi a type checking dinamico:
T Javascript, LISP, Perl, PHP, Python,
Javascript LISP Perl PHP Python Ruby
T Il type checking dinamico è più flessibile di
quello statico
ll t ti
T Ad esempio, un programma può costruire
strutture dati di forma mutevole a run time;
pertanto, il tipo di dato cambia a run time, e va
controllato a run time!
Linguaggi dinamici – A.A. 2009/2010
17
18. Type checking dinamico
T Godendo di un meccanismo di tipizzazione a
run time si possono effettuare gli
time,
assegnamenti più strani
T Ad esempio: $var = <token letto da file>;
T Il token può avere un qualunque tipo (intero,
stringa)
ti )
T Il type checker dinamico assegna il tipo
corretto a run time
T Provate a scrivere una cosa simile in C!
Linguaggi dinamici – A.A. 2009/2010
18
19. Type checking dinamico
T Ovviamente, la flessibilità si paga
T Un type checker dinamico dà minori garanzie a
priori rispetto ad un type checker statico,
proprio perché non può operare (solamente) a
tempo di compilazione
T Se, nell'esempio precedente, $ $var è intesa
essere una variabile intera che va sommata ad
un'altra variabile, ed a run time f
fornite una
stringa, l'interprete non potrà fare altro che
uscire (con tanti improperi!)
i ( ii i!)
T Il type checker dinamico non poteva sapere
dell'errore commesso in seguito dall'utente
Linguaggi dinamici – A.A. 2009/2010
19
20. Type checking dinamico
T Un type checker dinamico fa alcuni controlli a
tempo di compilazione
T I controlli si limitano alla correttezza sintattica
degli operatori
T I controlli a tempo di esecuzione sono, di
solito, molto più sofisticati, e coinvolgono il
lit lt iù fi ti ti i l
processo di identificazione di un tipo di una
espressione
i
T I linguaggi con type checking dinamico hanno
bisogno di quei controlli che il type checker
statico potrebbe dare loro
T Unit testing
Linguaggi dinamici – A.A. 2009/2010
20
21. Type checking statico e dinamico
T Alcuni linguaggi fanno uso di tecniche di type
checking statico e dinamico
T Java:
T Checking statico dei tipi
Ch ki t ti d i ti i
T Checking dinamico (a run time) per le
operazioni di d
i i downcasting ( i (ossia, il casting di
i i
una variabile di una classe base in una delle
sue sottoclassi)
Linguaggi dinamici – A.A. 2009/2010
21
22. Pro e contro nella pratica
T Type checking statico:
T Identifica errori a tempo di compilazione (non è
ben chiaro se ciò aumenta l'affidabilità del
programma)
T Permette la costruzione di codice che esegue
più velocemente
T Type checking dinamico:
T Permette al compilatore di eseguire i suoi
compiti molto più velocemente
T Permette l'uso di costrutti considerati illegali nei
linguaggi statici
T Permette una più rapida prototipazione
Linguaggi dinamici – A.A. 2009/2010
22
23. Tipizzazione forte
T Un linguaggio di programmazione adotta una
tipizzazione forte dei dati se una operazione
effettuata con operandi aventi tipo di dato non
co etto e e ped ta
corretto viene impedita
T Un'operazione di somma di interi con caratteri
T Un operazione
Un'operazione in cui si superano i limiti di un
array
T Non esiste il linguaggio completamente
tipizzato in maniera forte
T Java è f t
J fortemente ti i
t tipizzato (più del C e del
t ( iù d l d l
Pascal)
Linguaggi dinamici – A.A. 2009/2010
23
24. Tipizzazione debole
T Un linguaggio di programmazione adotta una
tipizzazione debole dei dati se una operazione
effettuata con operandi aventi tipo di dato non
co etto o
corretto non viene impedita
e e ped ta
T La tipizzazione debole fa spesso uso di
operatori di conversione (casting) per rendere
omogenei gli operandi
T Esempio: var x:= 5; var y:= “37”; x + y;
T In alcuni linguaggi (Visual Basic), y viene
convertito ad intero (x+y=42)
tit d i t ( + 42)
T In altri linguaggi (Javascript), x viene convertito
a stringa (x+y=”537”)
ti ( ”537”)
Linguaggi dinamici – A.A. 2009/2010
24
25. Tipizzazione safe
T Un linguaggio di programmazione adotta una
tipizzazione safe (sicura) dei dati se non
permette ad una operazione di casting di
p odu e u
produrre un risultato erroneo o un crash
su tato e o eo u c as
T Esempio (Visual Basic):
var x:= 5; var y:= “37”; var z = x + y;
37 ;
T In questo esempio, il risultato è 42
T L'operazione di conversione non f fallisce su
una stringa contenente un intero
T Se la stringa contenesse “Hi world”, la
conversione darebbe NULL e z avrebbe un
valore indefinito (senza crash)
Linguaggi dinamici – A.A. 2009/2010
25
26. Tipizzazione unsafe
T Un linguaggio di programmazione adotta una
tipizzazione unsafe (non sicura) dei dati se
permette ad una operazione di casting di
p odu e u
produrre un risultato erroneo o un crash
su tato e o eo u c as
T Esempio (C):
int x= 5; char y [] = “37”; char *z = x + y;
37 ; z
T Qui, z viene posto all'indirizzo di memoria 5
byte più in avanti di y
T Il contenuto di z non è definito, e può trovarsi
al di fuori dello spazio di indirizzamento del
l f i d ll i i di i d l
processo
T Una dereferenziazione di z può portare al crash
Linguaggi dinamici – A.A. 2009/2010
26
27. Tipizzazione e polimorfismo
T Con il termine polimorfismo si intende la
capacità (da parte di un linguaggio) di
differenziare il comportamento di un metodo o
d u ope ato e
di un operatore in funzione dell’entità a cui è
u o e de e t tà cu
applicato
T Alcuni linguaggi gestiscono il polimorfismo
anche a livello di tipi di dato
T Ad esempio in alcuni linguaggi è possibile definire
esempio,
una tabella associativa (tabella hash)
T Le chiavi e gli elementi possono essere valori di un
qualsiasi tipo (o quasi)
T Non è necessario predefinire una struttura dati
apposita per ogni possibile combinazione
Linguaggi dinamici – A.A. 2009/2010
27
28. Parte 1
Duck typing
yp g
Linguaggi dinamici – A.A. 2009/2010
28
29. Tipizzazione classica ad oggetti
T Nello schema classico di un linguaggio ad
oggetti,
oggetti gli attributi ed i metodi a disposizione
di un oggetto sono:
T quelli definiti dalla classe di appartenenza
dell'oggetto
T quelli ereditati dalle superclassi dell oggetto
dell'oggetto
T (i metodi) implementati tramite interfacce
T La l i
L relazione fra classi va dichiarata
f l i di hi
esplicitamente
T Parole chiavi (Java) class, extends, interface,
implements
Linguaggi dinamici – A.A. 2009/2010
29
30. Tipizzazione classica ad oggetti
T In tale schema, individuare il tipo di un
attributo e/o la signature di un metodo implica:
T individuare la classe di appartenenza
dell oggetto (binding)
dell'oggetto (binding), con il fine di individuare
un tipo per l'attributo oppure una signature
valida per il metodo
T In caso di mancata individuazione, ripetere il
controllo per tutte le superclassi (operation
dispatching – fino alla classe radice, es. Object)
T In altre parole individuare un attributo e/o una
parole,
signature implica trovare una classe adatta (fra
quelle imparentate) per l'oggetto
l oggetto
Linguaggi dinamici – A.A. 2009/2010
30
31. Tipizzazione classica ad oggetti
T Tali controlli possono essere effettuati
T A tempo di compilazione
T A tempo di esecuzione
T Di solito, si preferisce il tempo di compilazione
(il costo a tempo di esecuzione sarebbe troppo
elevato)
T C++ senza l’uso di puntatori
T In Java, è fatto a tempo di esecuzione
Linguaggi dinamici – A.A. 2009/2010
31
32. Duck typing
T In un linguaggio di programmazione ad oggetti
dinamico,
dinamico basato sul meccanismo di duck
typing, si rovescia tale concetto
T Posso evitare di dichiarare esplicitamente la
dipendenza di una classe da una superclasse
T Se i t
S istanzio un oggetto di tale classe ed uso i
i tt t l l d
suoi metodi/attributi, l'unica cosa che conta è
che i metodi/attributi siano definiti
h t di/ tt ib ti i d fi iti
T Tecnica utilizzata per implementare il
polimorfismo senza ricorrere alla ereditarietà
T Attenzione: il meccanismo di ereditarietà
esiste sempre!
Linguaggi dinamici – A.A. 2009/2010
32
33. Duck typing
T Un type checker basato su duck typing opera
tipicamente a livello di esecuzione
T Se vengono referenziati un attributo o un
metodo di un oggetto, si controlla solamente
oggetto
che il suddetto attributo o metodo siano
definiti per quell oggetto (duck test)
quell'oggetto
T Se sono definiti, si accede al dato o si invoca la
funzione
T Se non sono definiti, l'interprete esce con un
messaggio di errore
i
T Meccanismo molto più snello per il
compilatore e per il programmatore
Linguaggi dinamici – A.A. 2009/2010
33
34. Duck typing
T Quasi tutti i linguaggi dinamici moderni
adottano un meccanismo di gestione degli
attributi e delle signature degli oggetti basato
su duck typing
yp g
T Perl, PHP, Ruby, Python
T Anche alcuni linguaggi più classici possono
fare uso di un meccanismo di duck typing
T C++, tili
C++ utilizzato con i t
t template
l t
T Template: particolare classe parametrica che
implementa una funzionalità generica (es. lista)
i l t f i lità i ( li t )
T Il template parametrico viene istanziato in una
classe concreta durante la compilazione
Linguaggi dinamici – A.A. 2009/2010
34
35. Duck typing
T In Java, un meccanismo di duck typing è
ottenuto tramite i generics
T Generics, classe parametrizzabile su un’altra
classe
T public class Vettore<E> { … }
T …
T Vettore<Persona> v = new Vettore<Persona>
T Nell’oggetto istanziato ogni riferimento a E
(variabili, parametri, valori di ritorno) viene
concretizzato con la classe Persona
Linguaggi dinamici – A.A. 2009/2010
35
36. Programmazione polimorfa
T Il precedente esempio (stack.cpp) è un
classico della programmazione polimorfa
T Alcuni problemi di programmazione si
prestano bene ad una implementazione con le
seguenti caratteristiche
T È presente una funzione “generica”
t f i “ i ”
T I dettagli della funzione cambiano in base al tipo
degli
d li operandi di
Linguaggi dinamici – A.A. 2009/2010
36
37. Attenzione
T Non bisogna confondere la tipizzazione lasca
del C con quella dei linguaggi dinamici
T C
T Quello che interessa è l’occupazione della
memoria
T int i = ‘a’;
a;
T Funziona perché sizeof(char) <= sizeof(int)
T Linguaggi dinamici
Li i di i i
T Cercano di interpretare il significato dei valori in
modo dinamico
Linguaggi dinamici – A.A. 2009/2010
37