MdP Modèles de Programmation Emmanuel Chailloux Master LMFI - Modèles de Programmation - année 2014/2015 - 1 / 44 Informations sur le cours MdP Site http: //www-apr.lip6.fr/~chaillou/Public/enseignement/2014-2015/MdP/ Email [email protected] Master LMFI - Modèles de Programmation - année 2014/2015 - 2 / 44 Description de l’UE Comprendre les différents modèles de programmation séquentielle (impératif, fonctionnel, modulaire, objet) I Maîtriser leur mise en pratique dans le cadre du langage OCaml, I Apprécier la sûreté et la réutilisation apportéee par le typage statique I Savoir utiliser un environnement de développement pour Caml I Comprendre les différents modèles de programmation concurrente en fonction des modèles mémoire utilisés (mémoire partagée, mémoire répartie). mots clés : Panorama des langages de programmation, Types et déclarations, Mécanismes d’abstraction, Programmation par objets, Programmation fonctionnelle, Programmation modulaire, Systèmes de types, Programmation concurrente I Master LMFI - Modèles de Programmation - année 2014/2015 - 3 / 44 Plan du cours (1) 1. présentation de l’UE généralités sur les langages et les modèles de programmation, le noyau fonctionnel Caml : définitions et appels de fonction, valeurs fonctionnelles 2. le noyau fonctionnel : déclarations de types, filtrage de motifs, polymorphisme Exceptions : déclenchement, récupération et style de programmation 3. Traits impératifs : valeurs physiquement modifiables et structures de contrôle, variables de type faibles 4. Modules simples et paramétrés : séparation interface et implantation, compilation séparée, types abstraits de données 5. Objet I : classes, instances, héritage, liaison tardive Objet II : sous-typage et polymorphisme objet 6. Concurrence et répartition Master LMFI - Modèles de Programmation - année 2014/2015 - 4 / 44 Logiciels du cours indépendants des systèmes (Windows, Linux, Macosx, ...) : I langage Objective Caml 4.01 I I pré-installé sur les machines de l’école doctorale (à véririfer) à installer à la maison à partir du site de l’Inria : http://caml.inria.fr/ I Environnements de développement I Emacs et mode Tuareg http://www.gnu.org/software/emacs/ et http://tuareg.forge.ocamlcore.org/ I I Eclipse et plug-in Ocaide http///www.eclipse.org et http://www.algo-prog.info/ocaide/ Utilisation en ligne avec tryocaml : http://try.ocamlpro.com/ Master LMFI - Modèles de Programmation - année 2014/2015 - 5 / 44 Bibliographie Pascal Manourry. Programmation de droite à gauche et vice-versa, paracamplus, 2012. I Guy Cousineau et Michel Mauny. Approche fonctionnelle de la programmation. Dunod, 1995. I Sylvain Conchon et Jean-Christophe Filliâtre. Apprendre à programmer avec OCaml. Eyrolles, 2014. I Xavier Leroy et al. The Objective Caml system : documentation and user’s manual Inria, 2010. I Emmanuel Chailloux, Pascal Manoury et Bruno Pagano. Développement d’Applications avec Objective Caml. O’Reilly, 2000. I Philippe Nardel. Programmation fonctionnelle, générique et objet : Une introduction avec le langage OCaml. Vuibert, 2005 I Yaron Minsky, Anil Madhavapeddy, Jason Hickey. Real World OCaml, O’Reilly 2013 autres références sur : http://caml.inria.fr/about/books.en.html et I http://ocaml.org/ Master LMFI - Modèles de Programmation - année 2014/2015 - 6 / 44 Objective Caml I langage fonctionnel, I typé statiquement, I polymorphe paramétrique, I avec inférence de types, I muni d’un mécanisme d’exceptions, I et de traits impératifs I possèdant un système de modules paramétrés I et un modèle objet I exécutant des processus légers I et communiquant sur le réseau Internet, I indépendant de l’architecture machine. Master LMFI - Modèles de Programmation - année 2014/2015 - 7 / 44 Historique I I l’ancêtre : ML (meta-langage) de LCF (80) machines abstraites (84) I I I I la FAM : Cardelli la CAM : Curien, Cousineau spécifications : Standard ML (84 - Milner) premières implantations I I CAML - Suarez - Weis - Mauny (87) SML/NJ - Mc Queen - Appel (ATT - 88) I nouvelles implantations : Caml-light (90) Leroy - Doligez I modules paramétrés : Caml Special Light (95) I extension objet (96) I labels, options, variants polymorphes, modules récursifs, de 1ère classe,. . . I types algébriques généralisś (GADT) Master LMFI - Modèles de Programmation - année 2014/2015 - 8 / 44 Mise en œuvre (1) I compilateur natif (commande ocamlopt) I I 1 2 3 4 5 6 7 8 9 pour Intel, ARM, Sparc, HP-pa, PowerPC, . . . pour Linux, Macosx, Windows, . . . $ cat t.ml let f x = x + 1 ;; print_int (f 18) ;; print_newline () ;; $ ocamlopt -o tn.exe t.ml $ ./tn.exe 19 Master LMFI - Modèles de Programmation - année 2014/2015 - 9 / 44 Mise en œuvre (2) I compilateur byte-code (commande ocamlc) I 1 2 3 4 5 6 7 8 9 10 ligne de commande $ cat t.ml let f x = x + 1 ;; print_int (f 18) ;; print_newline () ;; $ ocamlc -i -custom -o tb.exe t.ml val f : int -> int $ ./tb.exe 19 Master LMFI - Modèles de Programmation - année 2014/2015 - 10 / 44 Mise en œuvre (3) I compilateur byte-code (commande ocaml) I 1 2 3 4 5 6 7 8 9 boucle d’interaction $ ocaml OCaml version 4.01.0 # let f x = x + 1 ;; val f : int -> int = <fun> # f 18 ;; - : int = 19 # #quit ;; $ I I I $ : invite Unix # : invite OCaml #quit : directive OCaml Master LMFI - Modèles de Programmation - année 2014/2015 - 11 / 44 Machine virtuelle BC la Zinc C C .o BC BC .o µ µ bibliothèque d’exécution C ocamlrun C .o .o µ compilateur O’CAML v1 -> v2 OC-v2 OC-v2 BC BC OC-v1 OC-v1 BC BC BC ocamlc BC µ bibliothèques de modules OC-v2 OC-v2 BC BC BC .cmo BC µ Master LMFI - Modèles de Programmation - année 2014/2015 - 12 / 44 Phrases du langage Se terminent par ;; I I expressions déclarations I I I de valeurs de types d’exceptions I déclarations de modules I déclarations de classes Notation qualifiée Module.nom pour accéder à un champs d’un module. Master LMFI - Modèles de Programmation - année 2014/2015 - 13 / 44 Noyau fonctionnel Master LMFI - Modèles de Programmation - année 2014/2015 - 14 / 44 Programmes en Objective Caml Seuls les programmes correctement typés peuvent être exécutés ! ! ! un programme est : I le calcul d’une expression I c’est-à-dire l’application d’une fonction à ses arguments I avec évaluation immédiate des arguments I et rupture d’évaluation si calcul impossible Master LMFI - Modèles de Programmation - année 2014/2015 - 15 / 44 Types de base, valeurs et fonctions I nombres I I int ([−230 , 230 − 1] sur 32 bits ou [−262 , 262 − 1 sur 64 bits) voir min_int et max_int float (IEEE 754) mantisse 53bits, exposant ∈ [−1022, 1023] I caractères : char I chaînes de caractères : string I booléens : bool Master LMFI - Modèles de Programmation - année 2014/2015 - 16 / 44 Opérations sur les nombres entiers + * / mod addition soustraction multiplication division entière modulo flottants +. addition -. soustraction *. multiplication /. division ** exponentiation opérateurs infixes ! ! ! 1 2 3 4 # # - 1 + 3;; : int = 4 1.8 *. 9.1;; : float = 16.38 Master LMFI - Modèles de Programmation - année 2014/2015 - 17 / 44 Fonctions sur les nombres ceil cos floor sin sqrt exp log log10 racine carrée exponentielle log népérien log en base 10 tan acos asin atan cosinus sinus tangente arccosinus arcsinus arctangente angles en radiant ! ! ! Master LMFI - Modèles de Programmation - année 2014/2015 - 18 / 44 Calculs sur les nombres (1) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # 1 + 2;; - : int = 3 # 9/2;; - : int = 4 # max_int + 1;; - : int = -4611686018427387904 # 9.1 /. 2.2;; - : float = 4.13636363636 # 1. /. 0.;; - : float = Inf Master LMFI - Modèles de Programmation - année 2014/2015 - 19 / 44 Calculs sur les nombres (2) 1 2 3 # 2 + 2.1;; This expression has type float but is here used with type int Un int ne peut pas remplacer un float ! ! ! 1 2 3 4 5 # sin;; - : float -> float = <fun> # asin 1.;; - : float = 1.57079632679 Master LMFI - Modèles de Programmation - année 2014/2015 - 20 / 44 Calculs sur les chaînes 1 2 3 4 5 6 7 8 9 10 11 # ’B’;; - : char = ’B’ # int_of_char ’B’;; - : int = 66 # "est une chaine";; - : string = "est une chaine" # (string_of_int 1987)^" est l’annee de CAML";; - : string = "1987 est l’annee de CAML" Master LMFI - Modèles de Programmation - année 2014/2015 - 21 / 44 Opérations sur les booléns et relations not && || = == <> != négation et séquentiel ou séquentiel égalité structurelle égalité physique négation de = négation de == & or < > <= >= synonyme pour et synonyme pour ou inférieur supérieur inférieur ou égal supérieur ou égal égalités et inégalités polymorphes ! ! ! = : ’a -> ’a -> bool == : ’a -> ’a -> bool Master LMFI - Modèles de Programmation - année 2014/2015 - 22 / 44 Produits cartésiens, n-uplets I constructeur de valeurs : , I constructeur de types : * accesseurs (couples) : fst et snd I 1 2 3 4 5 6 7 8 # (8,"mars");; - : int * string # (8,"mars",2013);; - : int * string * int # fst (8,"mars") ;; - : int = 8 # snd (8,"mars",2013) erreur de typage Master LMFI - Modèles de Programmation - année 2014/2015 - 23 / 44 Listes homogènes 1 2 3 4 5 6 7 8 9 10 11 I liste vide : [] I constructeur :: I type list I accesseurs List.hd et List.tl # [];; - : ’a list # 1::2::3::[];; - : int list # [1; 2; 3;];; - : int list # [1; "hello"; 3];; erreur de typage # List.hd [1.1; 1.2; 1.3];; - : float = 1.1 # List.hd [];; exception non récupérée Master LMFI - Modèles de Programmation - année 2014/2015 - 24 / 44 Expression conditionnelle Syntaxe: if expr1 then expr2 else expr3 1 2 3 4 5 6 7 8 # # # # - I expr1 de type bool I expr2 et expr3 de même type if 3 = 4 then 0 else 4;; : int = 4 if 5 = 6 then 1 else "Non";; : erreur de typage (if 3 = 5 then 8 else 10) + 5;; : int = 15 5 = 6 || 7 = 9;; : bool = false Master LMFI - Modèles de Programmation - année 2014/2015 - 25 / 44 Déclarations de valeurs (1) Déclarations globales: Syntaxe: let p = e 1 2 3 4 5 # let pi = 3.14159;; val pi : float = 3.14159 # sin (pi /. 2.0);; - : float = 0.999999999999 Master LMFI - Modèles de Programmation - année 2014/2015 - 26 / 44 Déclarations de valeurs (2) Déclatations locales: Syntaxe: let p = e1 in e2 1 2 3 4 5 6 7 # let x = 3 in let b = x < 10 in if b then 0 else 10;; - : int = 0 # b;; Unbound value b Master LMFI - Modèles de Programmation - année 2014/2015 - 27 / 44 Déclarations combinées Syntaxe: let p1 = e1 and p2 = e2 ... and pn = en ; ; 1 2 3 4 5 # let x = 1 and y = 2;; val x : int = 1 val y : int = 2 # x + y;; - : int = 3 Syntaxe: let p1 = e1 and p2 = e2 ... and pn = en in expr ; ; 1 2 # let a = 3.0 and b = 4.0 in sqrt(a*.a+.b*.b);; - : float = 5 Master LMFI - Modèles de Programmation - année 2014/2015 - 28 / 44 Valeurs fonctionnelles, fonctions Syntaxe: function p -> e 1 2 3 4 5 6 7 8 I fonction anonyme : function p -> e I de type : typede(p) -> typede(e) # function x -> x+1;; - : int -> int # (function x -> x+1) 2013;; - : int = 2014 # function x -> if x < 0 then -x else x;; - : int -> int # function x -> (function y -> 2*x+3*y);; - : int -> int -> int Master LMFI - Modèles de Programmation - année 2014/2015 - 29 / 44 Déclaration de valeurs fonctionnelles 1 2 3 4 # let succ = function x -> x+1;; succ : int -> int # succ 420;; - : int = 421 Syntaxe: let f = function p -> e ou let f p = e ou 1 2 3 4 5 6 7 8 9 10 let f (p) = e # let pred (x) = x -1;; pred : int -> int = <fun> # let f c = 2*(fst c) + 3*(snd c);; f : int * int -> int = <fun> # f (1,2);; - : int = 8 # let g = function x -> (function y -> 2*x + 3*y);; g : int -> int -> int = <fun> # g 1 2;; - : int = 8 Master LMFI - Modèles de Programmation - année 2014/2015 - 30 / 44 Portée des déclarations I 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 portée lexicale (liaison statique) # let p = q + 1;; (* erreur q inconnue *) # let p = p + 1;; (* erreur p inconnue *) # let p = 10;; # let addp x = x + p;; # addp 8;; # p;; addp : int ->int = <fun> - : int = 18 # let p = 40;; # addp 8;; p : int = 10 p : int = 40 - : int = 18 - : int = 40 Master LMFI - Modèles de Programmation - année 2014/2015 - 31 / 44 Récursivité Syntaxe: let rec p = expr 1 2 3 4 5 6 # let rec sigma x = if x = 0 then 0 else x + sigma(x-1);; sigma : int -> int = <fun> # sigma 10;; - : int = 55 récursion mutuelle: 1 2 3 4 5 6 7 # let rec odd x = if x = 0 then false else even(x-1) # and even x = if x = 0 then true else odd(x-1);; val odd : int -> bool = <fun> val even : int -> bool = <fun> # odd 27;; - : bool = true Master LMFI - Modèles de Programmation - année 2014/2015 - 32 / 44 Polymorphisme paramétrique (1) 1 2 3 4 5 6 7 8 9 10 11 I même code pour des arguments de types différents I la fonction n’utilise pas la structure de l’argument # let mp a b = a,b;; val mp : ’a -> ’b -> ’a * ’b = <fun> # let x = mp 3 6.8;; val x : int * float = 3, 6.8 # let y = mp true [1];; val y : bool * int list = true, [1] # fst x;; - : int = 3 Master LMFI - Modèles de Programmation - année 2014/2015 - 33 / 44 Polymorphisme paramétrique (2) 1 2 3 4 5 6 7 8 I même code pour des arguments de types différents I la fonction n’utilise pas la structure de l’argument # let id x = x;; val id : ’a -> ’a = <fun> # let app x y = x y;; val app : (’a -> ’b) -> ’a -> ’b = <fun> # app id 1;; - : int = 1 Master LMFI - Modèles de Programmation - année 2014/2015 - 34 / 44 Résumé des expressions rencontrées expr ::= constante | ( expr ) | ident | Mod.ident | op expr | expr infix-op expr | if expr then expr else expr | function ident -> expr | expr expr | expr , expr | epxr :: epxr | let [rec] ident = expr [ and ident = expr ]* in expr Master LMFI - Modèles de Programmation - année 2014/2015 - 35 / 44 Exemples (1) Comptage des éléments d’une liste: 1 2 3 4 5 6 7 8 9 10 11 12 13 # let rec long l = if l = [] then 0 else 1 + long (List.tl l);; val long : ’a list -> int = <fun> # long [2;4;7];; - : int = 3 # long [];; - : int = 0 # long [’A’; ’G’];; - : int = 2 Master LMFI - Modèles de Programmation - année 2014/2015 - 36 / 44 Exemples (2) Composition de fonctions: 1 2 3 4 5 6 7 8 9 10 # let compose f g x = f (g x);; val compose : (’a -> ’b) -> (’c -> ’a) -> ’c -> ’b = <fun> # let add2 x = x + 2 and mult5 x = x * 5;; val add2 : int -> int = <fun> val mult5 : int -> int = <fun> # compose mult5 add2 9;; - : int = 55 Master LMFI - Modèles de Programmation - année 2014/2015 - 37 / 44 Exemples (3) Application d’une fonction sur les éléments d’une liste: 1 2 3 4 5 6 7 8 9 10 11 12 13 # let rec map f l = if l = [] then [] else let t = List.hd l and q = List.tl l in (f t) :: (map f q) ;; val map : (’a -> ’b) -> ’a list -> ’b list = <fun> # let l1 = map add2 [7; 2; 9];; val l1 : int list = [9; 4; 11] # let l2 = map long [[’z’;’a’;’m’]; [’.’;’n’;’e’;’t’]];; val l2 : int list = [3; 4] Master LMFI - Modèles de Programmation - année 2014/2015 - 38 / 44 Filtrage de motif permet l’accès aux structures de données I en testant une valeur I en nommant une partie de la structure motif: I assemblage correct (syntaxe et type) d’objets I I I I I de types de base (int, bool,. . .) de paires, listes et constructeurs d’identificateurs du motif “sauvage” (_) ce n’est pas une expression (pas de calcul) Master LMFI - Modèles de Programmation - année 2014/2015 - 39 / 44 Syntaxe du filtage de motif Syntaxe: match e with p1 -> e1 | p2 -> e2 ...| pn -> en I filtrage séquentiel de e par les différents pi . I Si un des motifs correspond à la valeur de e, alors sa branche ei est évaluée. I tous les ei du même type, idem pout les pi I motif linéaire ( (x,x) interdit) I détection d’un filtrage exhaustif Master LMFI - Modèles de Programmation - année 2014/2015 - 40 / 44 Exemple : fonction imply 1 2 3 4 5 6 # let imply v = match v with (true,true) -> true | (true,false)-> false | (false,true)-> true | (false,false)->true;; val imply : bool * bool -> bool = <fun> Autre version: 1 2 3 4 # let imply v = match v with (true,x) -> x | (false,_) -> true;; val imply : bool * bool -> bool = <fun> Master LMFI - Modèles de Programmation - année 2014/2015 - 41 / 44 Warnings I 1 2 3 4 5 6 7 I 1 2 3 4 5 filtrage non exhaustif : # let f x = match x with (true, x) -> true | (false, false) -> true;; Warning: this pattern-matching is not exhaustive. Here is an example of a value that is not matched: (false, true) val f : bool * bool -> bool = <fun> cas inutile : # let f x = match x (a,b) -> true | (true,false) -> Warning: this match val f : bool * bool with false;; case is unused. -> bool = <fun> Master LMFI - Modèles de Programmation - année 2014/2015 - 42 / 44 Style Caml : définition par cas en utilisant le filtrage de motifs sur les différents constructeurs d’uns structure de données : 1 2 3 4 let rec long l = match l with [] -> 0 | _::q -> 1 + long q;; val long : ’a list -> int = <fun> 1 2 3 4 let rec map f l = match l with [] -> [] | t::q -> (f t) :: map f q;; val map : (’a -> ’b) -> ’a list -> ’b list = <fun> Master LMFI - Modèles de Programmation - année 2014/2015 - 43 / 44 Motif dans les déclarations I 1 2 3 4 5 6 7 8 I 1 2 3 Formes équivalentes: Syntaxe: match e with filtrage # # # - ≡ (function filtrage) e match (2,1) with (n,0) -> -1 | (0,n) -> 0 | (n,1) -> n | (n,d) -> n / d ;; : int = 2 function (n,0) -> -1 | (0,n) -> 0 | (n,1) -> n | (n,d) -> n / d ;; : int * int -> int = <fun> (function (n,0) -> -1 | (0,n) -> 0 | (n,1) -> n | (n,d) -> n / d) (2,1) ;; : int = 2 Déclarations déstructurantes: Syntaxe: let p = e p est un motif # let (x,y) = (3,true);; val x : int = 3 val y : bool = true Master LMFI - Modèles de Programmation - année 2014/2015 - 44 / 44