Langage de Programmation 2 (LP2) Langage de Programmation 2 (LP2) RICM3 Cours 6 : Polymorphisme, Typage Pascal Lafourcade Polytech 2009 - 2010 1 / 53 Langage de Programmation 2 (LP2) La dernière fois ◮ Flots ◮ Exceptions 2 / 53 Langage de Programmation 2 (LP2) Plan Polymorphisme Généralités sur le “Typage” Typage du let et let rec Typage des exceptions Bilan Application Conclusion 3 / 53 Langage de Programmation 2 (LP2) Polymorphisme Le polymorphisme : définitions Définitions ◮ Étymologiquement : plusieurs formes ◮ En informatique : capacité d’une fonction à « s’adapter » à des arguments de type différent Deux espèces (hors langages à objets) : ◮ polymorphisme ad-hoc ex : + sur les entiers, les flottants, les chaîne. . . dans chaque type, le sens (le code exécuté) est différent ◮ polymorphisme paramétrique ex : @ sur les listes d’entiers, de flottants, de chaînes. . . le code exécuté est uniformément le même 5 / 53 Langage de Programmation 2 (LP2) Polymorphisme Exemple basique * Fonction identité type : let id = fun x → x Application : ◮ à des entiers : id 3 ◮ à des arbres : id (N (N (F, 7, F), 2, N (F, 5, F))) ◮ à des fonctions : id (fun n → (n +3)) ◮ à elle-même : id id, id id 3.14 [ ⇒ hors théorie des ensembles] 6 / 53 Langage de Programmation 2 (LP2) Polymorphisme Autres exemples * Paire # let pairing x y = (x,y) ; ; type : Compositions de fonctions let comp g f = fun x → g (f x) type : FAUX type : 7 / 53 Langage de Programmation 2 (LP2) Polymorphisme Autres exemples * Ces fonctions acceptent tous les types possibles .... ◮ ’a, ’b, ... sont des variables de types ◮ Un type contenant des variables est dit polymorphe ◮ Pour tout a, a donne a .... ◮ ∀a.(a → a) 8 / 53 Langage de Programmation 2 (LP2) Polymorphisme Évaluation de l’itération fonctionnelle * Itération d’une fonction let rec iter n f = if n = 0 then id else comp f (iter (n − 1) f ), type ? let plus3 = (+) 3 iter 2 plus3 ⊲ ⊲ ⊲ ⊲ ⊲ ⊲ ⊲ comp plus3 (iter 1 plus3) comp plus3 (comp plus3 (iter 0 plus3)) comp plus3 (comp plus3 id) comp plus3 (comp ((+) 3) (fun x → x)) comp plus3 (fun y → ((+) 3 ((fun x → x) y ))) comp ((+) 3 (fun y → ((+) 3 ((fun x → x) y )))) fun z → ((+) 3 ((fun y → ((+) 3 ((fun x → x) y ))) z)) Dans un langage avec évaluation du corps de la fonction (6= ML, dont Ocaml), réductions supplémentaires : ⊲ fun z → ((+) 3 (fun y → ((+) 3 y )) z) 9 / 53 Langage de Programmation 2 (LP2) Polymorphisme Exemple : pas toujours fonctionnels ◮ # [] ; ; - : ’a list = [] ◮ # fun x -> x : : [] ; ; ◮ # fun x -> x + 1 : : [] ; ; - : int -> int list = <fun> 10 / 53 Langage de Programmation 2 (LP2) Polymorphisme Le polymorphisme dans les données (1) Listes type α liste = Nil | Cons of α × α liste let rec app l 1 l 2 = match l 1 with | Nil → l 2 | Cons (x, l 1) → Cons (x, app l 1 l 2) 11 / 53 Langage de Programmation 2 (LP2) Polymorphisme Le polymorphisme dans les données (2) Application ◮ à des entiers : [3 ; 0 ; 8 ] ◮ à des arbres : [N (F, 7, F) ; F ; N (F, 5, F)] ◮ à des fonctions : [fun n → (n +3) ; (∗) 6 ; fact] ◮ à des fonctions polymorphes : [ (fun x → x) ; (fun x → raise Exc) ] ◮ à des listes : [[1 ; 2 ; 3 ] ; [1 ; 5 ] ; [] ; [7 ; 6 ; 2 ]]] ⇒ hors théorie des ensembles Attention à l’uniformité ! 12 / 53 Langage de Programmation 2 (LP2) Polymorphisme Le polymorphisme dans les données (3) Type option (en standard) type α option = None | Some of α Technique possible pour les fonctions partielles let tete l = match l with | Nil → None | Cons (x, _) → Some (x) Type : 13 / 53 Langage de Programmation 2 (LP2) Polymorphisme Le polymorphisme ad-hoc en Ocaml Sur les opérateurs de comparaison : =, <, <=, . . . α → α → bool Disponible sur toutes les structures de données ◮ entiers : 14 < 5 +5 ; caractères, booléens, chaînes ◮ listes : [3 ; 4 ] < [2 ; 5 ; 7 ] ; arbres Mais pas sur les types fonctionnels, ex : α → α : id = id 14 / 53 Langage de Programmation 2 (LP2) Polymorphisme Exemple de polymorphisme ad-hoc en Ocaml * type (α, β) abr = F | N of (α, β) abr × α × β × (α, β) abr let rec cherche x = function | F → None | N (g , y , v , d) → if y = x then Some (v ) else if y < x then cherche x g else cherche x d 15 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Système de types ◮ Types de données ◮ ◮ ◮ simples : numériques, booléens, chaînes structurés : produits (n-uplets, records), sommes (choix) Types fonctionnels fonction = valeur ordinaire ◮ toutes combinaisons permises, ex. listes de fonctions 17 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Types Les types sont inférés automatiquement Pour les données ◮ Types de base : int, float, char, string, bool, unit ◮ Types construits : produits (juxtaposition) et sommes (choix) Pour les fonctions Exemple : succ int → int Types polymorphes (généricité ADA) Exemple : test d’égalité (=) α → α → bool 18 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Typage dans un environnement Γ ⊢ expression : type Γ environnement de typage = liste d’associations x 7→ t, où x est un nom et t un type Exemples ◮ nbr 7→ int ⊢ nbr + 4 : int ◮ nbr 7→ int; b1 7→ bool ⊢ nbr + 4 : int ◮ nbr 7→ int; b1 7→ bool; nbr 7→ float ⊢ nbr +. 3.14 : float 19 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Règles initiales de typage Constantes littérales Γ ⊢ 0 : int Et similairement pour . . . , −2, −1, 1, 2, . . ., les booléens, les flottants, les caractères, les chaînes, etc. Gestion de l’environnement de typage Γ; x 7→ t ⊢ x : t Γ ⊢ x :t x 6= y Γ; y 7→ u ⊢ x : t NB. Environnement parcouru à partir de la droite 20 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Expression conditionnelle Expression = ◮ valeur (exemple : un entier) ◮ if B then E1 else E2 Règle de typage Γ ⊢ B : bool Γ ⊢ E1 : t Γ ⊢ E2 : t Γ ⊢ (if B then E1 else E2 ) : t Remarques ◮ Type calculé à la fois pour E1 et E2 (6= valeur) ◮ Différence entre le typage statique et l’évaluation dynamique : système de types décidable 21 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Types nommés type t = T Où t est un nom et T une expression de type Exemples ◮ type nom = string ◮ type test_int = int →bool On a un environnement statique supplémentaire d’associations t 7→ T Pour alléger, cet environnement est omis dans la suite, on écrira simplement déf T t = = 22 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Typage des couples et n-uplets Construction Γ ⊢ A:t Γ ⊢ B :u Γ ⊢ (A, B) : t × u Similairement pour des n-uplets Décomposition Par filtrage, cf. plus bas. 23 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Enregistrements = produits avec champs nommés Autres langages : record ADA, struct C Il faut nommer le type type r = {c1 : T1 ;. . . cn : Tn } Accès aux champs (mathématiquement : projections) en notation pointée Exemples ◮ ◮ type ic = { en : int ; ca : char } exemple de valeur : { en = 3 ; ca = ′ z′ } let cpl = { en = 3 ; ca = ′ z′ } in succ cpl.en ⊲∗ 4 type fa = { fct : int → int ; arg : int } let cp = { fct = fun x → x + 1 ; arg = 7 } in cp.fct cp.arg ⊲∗ 8 24 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Typage des enregistrements déf {c : T ; . . . c : T } On suppose r = 1 n n = 1 Construction Γ ⊢ E1 : T1 . . . Γ ⊢ En : Tn Γ ⊢ {c1 = E1 ; . . . cn = En } : r Décomposition Pour tout i , 1 ≤ i ≤ n, Γ ⊢ E :r Γ ⊢ E .ci : Ti Ou par filtrage, cf. plus bas. 25 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Fonctions A, B et E sont des expressions Notation mathématique : λx.E Notation Ocaml : fun x → E Règles de typage Γ ⊢ A:t →u Γ ⊢ B :t Γ ⊢ AB :u Γ, x 7→ t ⊢ E : u Γ ⊢ fun x→ E : t → u 26 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Typage L’environnement Γ0 initialement chargé (appelé Pervasives) contient : ◮ (+) 7→ int → int → int ; (−) 7→ int → int → int ; etc. ◮ (+.) 7→ float → float → float ; (−.) 7→ float → float → float ; ◮ (&&) 7→ bool → bool → bool ; (||) 7→ bool → bool → bool ; ◮ voir manuel Γ0 ⊢ (+) : int → int → int Γ0 ⊢ 3 : int Γ0 ⊢ (+) 3 : int → int Γ0 ⊢ (+) 3 2 : int Γ0 ⊢ 2 : int 27 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Exemple Γ, x 7→ t ⊢ E : u Γ ⊢ fun x→ E : t → u Γ ⊢ A:t →u Γ ⊢ B :t Γ ⊢ AB :u Γ, x 7→ t ⊢ E : u Γ ⊢ fun x→ E : t → u Vérifier que : Γ0 ⊢ fun x→ x + 1 : int → int 28 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Exercice Sachant que l’environnement Γ0 contient succ 7→ int → int (et aucun autre couple succ 7→ t) vérifier que Γ0 ⊢ fun n→ succ (succ n) : int → int Notation (pour raison de place) ◮ ◮ déf succ s = = déf Γ , n 7→ int Γ1 = = 0 29 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Tableaux Mathématiquement :fonctions à domaine fini [0 . . . n−1] Example [ | true; false; true; true; false | ] correspondrait à une fonction de type [0 . . . 4] → bool En réalité ◮ [ | true; false; true; true; false | ] : bool array ◮ [0 . . . 4] n’est pas un type Soit T un tableau d’éléments de type t, i.e. T : t array Alors fun i → T .(i ) : int → t Mais définie seulement sur [0 . . . Array.lengthT −1] 30 / 53 Langage de Programmation 2 (LP2) Généralités sur le “Typage” Règles de typage pour les tableaux ∀i , 0 ≤ i < n ⇒ Γ ⊢ Ai : t Γ ⊢ [ |A0 ; . . . ; An−1 | ] : t array Γ ⊢ A : t array Γ ⊢ B : int Γ ⊢ A.(B) : t NB. Le typage ne vérifie pas les bornes (problème indécidable) 31 / 53 Langage de Programmation 2 (LP2) Typage du let et let rec Typage du let Γ ⊢ A:t Γ, x 7→ t ⊢ B : u Γ ⊢ let x = A in B : u Exemple # let x = 5 in x ; ; - : int = 5 Γ ⊢ 5 : int Γ, x 7→ i nt ⊢ x : i nt Γ ⊢ let x = 5 in x : int 33 / 53 Langage de Programmation 2 (LP2) Typage du let et let rec Exercice Γ ⊢ A:t Γ, x 7→ t ⊢ B : u Γ ⊢ let x = A in B : u Vérifier le type de : # let succ = fun x -> x + 1 in succ 1 ; ; - : int = 2 val x : int -> int = <fun> 34 / 53 Langage de Programmation 2 (LP2) Typage du let et let rec Typage du let rec Γ, x 7→ t ⊢ A : t Γ, x 7→ t ⊢ B : u Γ ⊢ let rec x = A in B : u Exemple : fact I # let rec fact n = if n = 0 then 1 else n* (fact (n-1)) ; ; val fact : int -> int = <fun> 35 / 53 Langage de Programmation 2 (LP2) Typage du let et let rec Typage du filtrage (match) type t = C1 of T1,1 × . . . T1,n1 | . . . | Cp of Tp,1 × . . . Tp,np Posons match E with .. . déf M = = |Ci (x1 , . . . xn ) → Ei i .. . où chaque expression Ei dépend de x1 . . . xni . E :t ∀i , 1 ≤ i ≤ p, Γ; x1 → 7 Tp,1 . . . xni 7→ Tp,ni ⊢ Ei : T Γ ⊢ M :T 36 / 53 Langage de Programmation 2 (LP2) Typage du let et let rec Typage du match Exemple : fact II # let rec fact n = match n with | 0 -> 1 | n -> n* (fact (n-1)) ; ; val fact : int -> int = <fun> 37 / 53 Langage de Programmation 2 (LP2) Typage du let et let rec En somme, qu’est-ce qu’un type ? Moyens de construction élémentaires : (principes d’introduction) Indiquent les valeurs du type (infos non réductibles) ◮ produits (ex. record Pascal, struct C, {} Ocaml, * ML) ◮ sommes (sommes ML, articles avec variantes Pascal) ◮ exponentielles (fonctions, tableaux) Procédés d’utilisation élémentaires : (principes d’élimination) ◮ produits (projections, champs) ◮ sommes (filtrage) ◮ exponentielles (application) Symétrie introduction / élimination 38 / 53 Langage de Programmation 2 (LP2) Typage des exceptions Exceptions try E with | ListeVide → E1 | Alarme (n, b) → E2 (n, b) | Not_found → E3 | Division_by_zero → E4 déf == T (une expression) E , E1 , E2 (n, b), E3 , E4 , . . . doivent avoir le même type, qui est le type de l’expression entière T . E :t E1 : t E2 (n, b) : t T :t E3 : t E4 : t 40 / 53 Langage de Programmation 2 (LP2) Bilan Rappel des règles de typage Γ ⊢ 0 : int Γ; x 7→ t ⊢ x : t Γ ⊢ x :t x 6= y Γ; y 7→ u ⊢ x : t Γ ⊢ B : bool Γ ⊢ E1 : t Γ ⊢ E2 : t Γ ⊢ (if B then E1 else E2 ) : t Γ ⊢ A:t Γ ⊢ B :u Γ ⊢ (A, B) : t × u Γ ⊢ E1 : T1 . . . Γ ⊢ En : Tn Γ ⊢ {c1 = E1 ; . . . cn = En } : r Pour tout i , 1 ≤ i ≤ n, Γ ⊢ E :r Γ ⊢ E .ci : Ti 42 / 53 Langage de Programmation 2 (LP2) Bilan Rappel des règles de typage Γ ⊢ A:t →u Γ ⊢ B :t Γ ⊢ AB :u Γ, x 7→ t ⊢ E : u Γ ⊢ fun x→ E : t → u Γ ⊢ A:t Γ, x 7→ t ⊢ B : u Γ ⊢ let x = A in B : u Γ, x 7→ t ⊢ A : t Γ, x 7→ t ⊢ B : u Γ ⊢ let rec x = A in B : u E :t ∀i , 1 ≤ i ≤ p, Γ; x1 7→ Tp,1 . . . xni 7→ Tp,ni ⊢ Ei : T Γ ⊢ M : T = match... 43 / 53 Langage de Programmation 2 (LP2) Application Parcours de types mutuellement récursifs type arbre = Feuille of int | Foret of foret and foret = Fvide | F1 of arbre * foret Utilisation de fonctions mutuellement récursives let rec somme a = match a with | Feuille (n) → n | Foret (f ) → somfo f and somfo f = match f with | Fvide → 0 | F1 (a, f ) → somme a + somfo f 45 / 53 Langage de Programmation 2 (LP2) Application Exercice : repousser les négations vers les extrémités* type boolexpr = | Vrai | Faux | Var of string | Neg of boolexpr | Et of boolexpr * boolexpr | Ou of boolexpr * boolexpr type boolexprnf = | Vrainf | Fauxnf | Varnf of string | Negnf of boolexprnf | Etnf of boolexprnf * boolexprnf | Ounf of boolexprnf * boolexprnf let rec pousse = function let | Vrai → Vrainf | Faux → Fauxnf | Var (v ) → Varnf (v ) | Neg (p) → nie p | Et (p,q) → Etnf (pousse p, pousse q) | Ou (p,q) → Ounf (pousse p, pousse q) rec nie = function | Vrai → Fauxnf | Faux → Vrainf | Var (v ) → Negnf (Varnf (v )) | Neg (p) → p | Et (p,q) → Ounf (nie p, nie q) | Ou (p,q) → Etnf (nie p, nie q) Chercher l’erreur... et la corriger ... par typage 47 / 53 Langage de Programmation 2 (LP2) Application Solution* Analyse par typage 49 / 53 Langage de Programmation 2 (LP2) Conclusion Aujourd’hui ◮ Typage 51 / 53 Langage de Programmation 2 (LP2) Conclusion Prochaine fois ◮ Polymorphisme ◮ Inférence de type 52 / 53 Langage de Programmation 2 (LP2) Conclusion Merci de votre attention. Questions ? 53 / 53