Introduzione ai Sistemi di Tipi Silvia Crafa silvia@dsi.unive.it
Come nascono i tipi in informatica Cos è un tipo? Perché servono i tipi nei linguaggi di programmazione? Vediamo come nascono i tipi partendo da universi non tipati
Stringhe di bit nella memoria non tipato = esiste un unico tipo: la stringa di bit 10110100 11101001 00100011 01110001 carattere? numero? programma? Il significato di una cella dipende da un interpretazione esterna
Teoria degli insiemi La matematica si può rappresentare con gli insiemi 0 Ø 1 {Ø} 2 {Ø, {Ø}} Doppio { (1,2), (2,4), (3,6), } R = { X X X} elemento! insieme! Uso i tipi per distinguere gli oggetti a seconda del loro grado di funzionalità
Uso informale dei Tipi I tipi nascono per distinguere gli oggetti a seconda del loro significato e del loro uso TIPO = insieme di oggetti che hanno un comportamento uniforme Es: interi, funzioni
Uso informale dei Tipi Possiamo pensare al mondo non tipato come se fosse tipato.. intero Fun: int int 10110100 11101001 00100011 01110001 E illusione! E facile violare le distinzioni di tipo
I Sistemi di Tipi Ci permettono di dimenticare le rappresentazioni degli oggetti. Impongono vincoli sull uso degli oggetti, assicurandone una manipolazione corretta. 10110100 Intero 11101001 Stringa + 1 NO!! Fun: 00100011 int int 01110001 Intero
I Sistemi di Tipi Sono dei metodi formali per classificare le espressioni di un programma a seconda della loro struttura (es. M è un array ) o del loro comportamento (es. F prende un intero e restituisce una lista di booleani ). Il loro scopo è garantire l assenza di errori durante l esecuzione del programma (es. nessun accesso oltre i limiti di un array es. nessun dato segreto è rivelato dal programma in modo né esplicito né implicito ).
I Sistemi di Tipi Un sistema di tipi è quella componente del linguaggio che tiene traccia dei tipi delle variabili e delle espressioni di un programma. double fun (int, int); int x; int y; fun(x,y); f(x+y, x-y); Dato un sistema di tipi, bisogna dimostrarne la soundness: tutti i programmi ben tipati non generano errori durante la loro esecuzione.
Formalizziamo un Sistema di Tipi Formalizziamo la sintassi del linguaggio: M ::= x variabile termini true false n if M then M else M costanti: bool e int condizionale Fun(x:τ ) = M funzione M(M) applicazione tipi τ ::= bool int tipi base τ > τ tipi funzione
Esempi di termini if true then 5 else 7 Fun(x:bool)= if x then 5 else 7 F(x:bool)=if x then 5 else 7 ( false ) F(x:bool)=if x then 5 else 7 ( 4 ) Fun(x:int)= if M then x else 7
Esempi di termini F(x:int)= F(y:int)= if M then x else y Fun (x:int->int)= if M then x(3) else x(8) F(x:int->int)=if M then x(3)else x(8)( F(y:int)=y )
Semantica del linguaggio F(x:τ)= M ( N ) M[x:=N] if true then M else N M if false then M else N N F(x:int->int)=if M then x(3)else x(8)( F(y:int)=y ) --> if M then 3 else 8 F(x:bool)=if x then 5 else 7 ( false ) -> -> 7
Giudizi di tipo Γ M : τ Il termine M ha tipo τ sotto le assunzioni Γ Es. x:int x+5:int (var) (bool T) (bool F) Γ, x : τ x : τ Γ true : bool Γ false : bool
Regole di Tipo (If) Γ M : bool Γ N1 : τ Γ N2 : τ Γ if M then N1 else N2 : τ ( Funzione ) Γ, x : τ M : τ Γ Fun(x : τ) =M : τ > τ ( Applic ) Γ M : τ > τ Γ M (N) : τ Γ N1 : τ
Regole di Tipo (If) Γ M : bool Γ N1 : τ Γ N2 : τ Γ if M then N1 else N2 : τ ( Funzione ) Γ, x : τ M : τ Γ Fun(x : τ) =M : τ > τ ( Applic ) Γ M : τ > τ Γ M (N) : τ Γ N1 : τ
Regole di Tipo (If) Γ M : bool Γ N1 : τ Γ N2 : τ Γ if M then N1 else N2 : τ ( Funzione ) Γ, x : τ M : τ Γ Fun(x : τ) =M : τ > τ ( Applic ) Γ M : τ > τ Γ M (N) : τ Γ N1 : τ
Derivazioni di tipo Γ true : bool Γ 5 : int Γ 7 : int Γ if true then 5 else 7 : int Γ, x : bool x : bool Γ 5 : int Γ 7 : int Γ, x : bool if x then 5 else 7 : int Γ Fun(x:bool)= if x then 5 else 7 : bool -> int
Typechecking Γ, x:int->int x: int->int Γ, x: int->int 3:int Γ, x : int->int x(3):int Γ, x : int->int if M then x(3) else x(8): int Γ F(x:int->int)= if M then x(3) else x(8): (int->int)-> int
Typechecking F(x:int)= F(y:int)= if M then x else y : int -> ( int -> int ) F(x:int->int)=if M then (3)else(8)(F(y:int)=y) : int F(x:bool)=if x then 5 else 7 ( false ) : int F(x:bool)=if x then 5 else 7 ( 4 ) NON TIPA!!
Typechecking I tipi distinguono i programmi che si comportano bene da quelli che contengono errori Es di errori: F(x:bool)= if x then 5 else 7 (4) F(x:int )= x(8) F(x:int->int) = x(x) Come facciamo a fidarci dei tipi?
Type Soundness Subject reduction: Se Γ M : τ e M -> N allora Γ N : τ i.e. un termine ben tipato evolve in un termine ben tipato. Abbiamo visto che un errore è un termine che non ha tipo. Soundness: Se Γ M : τ allora la computazione di M non produce errori.
Cosa sono i Sistemi di Tipi? I sistemi di tipi rappresentano un metodo formale di analisi statica della correttezza dei programmi. Il tipo di un termine esprime un informazione statica sul suo comportamento dinamico. L analisi statica è approssimata: se M è tipato non produce errori, ma ci sono programmi che non producono errori ma che non sono tipabili : if false then F(x:int)=x(8) else 1
Cosa si può fare con i Tipi Oltre ad individuare gli errori di programmazione i tipi permettono di esprimere proprietà e ragionare sul comportamento dei programmi M ::= x variabile λ(x:τ ).M funzione Fun(x:τ )= M λ calcolo M(M) Buffer overfow applicazione τ ::= b τ > τ Termini tipati = λ-termini normalizzanti
Cosa si può fare con i Tipi Oltre ad individuare gli errori di programmazione i tipi permettono di esprimere proprietà e ragionare sul comportamento dei programmi M ::= x variabile λ(x:τ ).M funzione Fun(x:τ )= M λ calcolo M(M) applicazione τ ::= b τ > τ Termini tipati = λ-termini normalizzanti
Advanced features Type inference Subtyping Type equivalence Polimorfismo Encapsulation e object types Tipi nei linguaggi concorrenti: ragionare sui comportamenti dei processi.
Subtyping τ <: τ Tipi = insiemi di valori. <: = sottoinsieme Un elemento di tipo τ è anche di tipo τ ( int <: real) Il subtyping permette di usare i tipi in modo più flessibile: Γ M : τ τ <: τ Γ M : τ Γ If true then 5 else 8.3 : real
Subtyping con le funzioni Una funzione di tipo τ > σ τ <: τ σ <: σ τ > σ <: τ > σ accetta elementi di tipo τ quindi anche di un sottotipo τ di τ (controvaianza) restituisce elementi di tipo σ quindi anche di un sopratipo σ di σ (covarianza) es. real -> int <: int -> real
Polimorfismo Funzioni polimorfe sono funzioni che lavorano in modo uniforme su elementi di tipi diversi. Es: ordinamento di array Servono per scrivere codice più strutturato e per evitare ripetizioni di codice simile Come si tipano? ordina : α. Array(α) -> Array(α)
Encapsulation Nella programmazione strutturata (es. OO, ) Suddivido codice in vari moduli, ognuno con una funzionalità specifica ne esporto solo l interfaccia, che fissa il modo in cui possono essere usati i moduli da fuori Come nel caso della memoria fisica, uso i tipi per nascondere l implementazione interna dei moduli mostrare una specifica interfaccia: quali operazioni si possono fare dall esterno
Encapsulation & Object Types Subtyping Ereditarietà numero_aereo modello n_posti_business n_posti_economica anno_revisione Prenota(num, tipo) Disdici(num, tipo) Fai_tagliando( ) int string int int Array(int) ( int, char ) -> int ( int, char) -> void void -> void Tipo oggetto: Aereo Aereo_agenzia numero_aereo Prenota(num, tipo) Disdici(num, tipo) int ( int, char ) -> int ( int, char ) -> void Aereo_officina numero_aereo int modello string anno_revisione Array(int) Fai_tagliando( ) void -> void
Argormenti di ricerca Nella programmazione di codice mobile e concorrente scrivere sistemi di tipi per individuare staticamente errori di sicurezza: Resource access control Information flow: if h=0 then l=2 else l=3 opp. Agente che visita sito di commercio elettronico Secrecy di dati con o senza crittografia Controllo della disseminazione di informazioni (DRM) Legame tra i tipi e la semantica comportamentale
Argomenti di ricerca C è tanto da fare dagli aspetti più teorici (λ-calcolo di ordine superiore, tipi ricorsivi, object types, tipi e semantiche ) allo studio di efficienza/complessità: type inference agli aspetti di implementazione: sfruttare tipi per certificazione di programmi.