Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Organisation Organisation Programmation Fonctionnelle Avancée I 12 cours, dernier cours le 15 décembre. I 12 TP. Premier : le 16 septembre. Dernier : 16 décembre. Ralf Treinen I Pas de cours le 22/9 ! I Il y a un projet de programmation, mais pas de partiel Université Paris Diderot UFR Informatique Institut de Recherche en Informatique Fondamentale I Contrôle de connaissances : 1 3 [email protected] ∗ projet + 2 3 ∗ exam I Note 2ème session : 12 septembre 2016 max( c 1 3 ∗ projet + 2 3 ∗ exam2, exam2) Roberto Di Cosmo et Ralf Treinen Programmation Fonctionnelle Avancée Organisation Organisation I http://www.pps.univ-paris-diderot.fr/~treinen/ teaching/pfav/ I Support : copies des transparents I Il y a des ressources en ligne (voir la page web du cours) I Les TP sont assurés par Pierre Letouzey I Il est indispensable d'assister au cours et aux TD/TP Programmation Fonctionnelle Avancée Organisation Le projet I Le sujet détaillé sera mis en ligne plus tard. I Projet complet à rendre (la date limite sera annoncée plus tard). I Soutenance prévue pendant la période des examens en janvier. I Peut être fait en binôme, mais la notation est individuelle. Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Organisation Organisation Pré-requis de ce cours I Ce cours est la continuation du cours Fonctionnelle Pour vous rafraîchir la mémoire ou vous mettre à niveau PF5 - Programmation du L3. I Mais il peut être suivi par des étudiants qui ont suivi un autre cours de programmation fonctionnelle en OCaml (même si niveau L1) I ... I Les transparents du cours du L3 I Le document I Dans le livre Caml ... I ou un autre langage fonctionnel (Scheme, Haskell). I I I Dans ce cas il va falloir vous mettre à niveau. I Programmation Fonctionnelle Avancée Organisation OCaml : Le MOOC Initiation à la programmation fonctionnelle par Jean-Christophe Filliâtre, jusqu'à section 2.1.2 incluse. Développement d'applications avec Objective : Chapitre Chapitre Chapitre Chapitre 2 : Programmation fonctionnelle 3 : Programmation impérative 7 : Compilation 14 : seulement Modules Simples Programmation Fonctionnelle Avancée Introduction Objectif du cours I 7 semaines, 26/9 -> 12/12 I https://www.fun-mooc.fr/courses/parisdiderot/ 56002S02/session02/about John Carmack Sometimes, the elegant implementation is a function. Not a method. Not a class. Not a framework. Just a function. I gratuit, inscription sur FUN I en VO ou VOSTF Dans ce cours, nous allons explorer ensemble avancés de la programmation fonctionnelle en utilisant le langage OCaml I plusieurs aspects I I Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction Programmation fonctionnelle Programmation fonctionnelle Les fonctions sont des valeurs de première classe fonctionnels, les fonctions sont des entités de première classe, i.e. une fonction Dans les langages dits I peut être construite sans besoin d'être nommée : il y a des expressions dont la valeur est une fonction ; I être dénie et nommée au même moment. Il y a deux mécanismes indépendants : I des expressions fonctionnelles, I lier un identicateur à une valeur (fonctionnelle ou pas). Programmation Fonctionnelle Avancée Exemples (fonctions1.ml) ( ∗ une v a l e u r f o n c t i o n n e l l e ∗ ) function x −> x +2;; ( ∗ d e f i n i r e t nommer une f o n c t i o n ∗ ) let f = function x −> x ;; (∗ p l u s c o u r t ∗) let f x = x ;; Programmation Fonctionnelle Avancée Introduction Introduction Programmation fonctionnelle Programmation fonctionnelle Les fonctions sont des valeurs de première classe Exemples (fonctions2.ml) ( ∗ f o n c t i o n s dans un r e c o r d ∗ ) type ' a let foo Dans les langages dits fonctionnels, les fonctions sont des entités de première classe, i.e. une fonction I peut être placée à l'intérieur d'une structure de données. I peut être passée en paramètre à une fonction, et retournée comme résultat d'une fonction. foo . f f o o = {n : i n t ; f=fun = { n =42; f : 'a −> x −> x} ;; ;; 33;; ( ∗ f o n c t i o n s dans une p a i r e . let ' a} fp = ( ( fun x −> x +1) , ∗) ( fun x −> x∗x ) );; ( ∗ a t t e n t i o n aux p a r a n t h e s e s ∗ ) let fp = ( fun x −> x +1 , fun x −> x∗x );; ( ∗ e x t r a c t i o n des f o n c t i o n s d ' une p a i r e ∗ ) ( fst fp ) 42;; ( fst fp ) ( ( snd ( fst fp ) ( snd fp ) fp ) 10);; 10;; ( ∗ a t t e n t i o n aux p a r a n t h e s e s ∗ ) Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction Programmation fonctionnelle Programmation fonctionnelle Exemples (fonctions3.ml) let x = 2∗ x double Les fonctions sont des valeurs de première classe ;; ( ∗ une f o n c t i o n avec un argument f o n c t i o n n e l ∗ ) let apply_twice_to apply_twice_to f n = f double (f n);; 5;; compose f g = fun compose double ( fun compose double double x x −> −> première classe, i.e. une fonction f (g x );; I peut créée dynamiquement ; I peut être dénie localement à une fonction. x +2);; 10;; Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction Programmation fonctionnelle Programmation fonctionnelle Exemples (fonctions4.ml) let fonctionnels, les fonctions sont des entités de I peut être partiellement appliquée ; ( ∗ arguments , e t r e s u l t a t f o n c t i o n n e l s ∗ ) let Dans les langages dits mul x Exemples (fonctions5.ml) ( ∗ f o n c t i o n s l o c a l e a une a u t r e f o n c t i o n ∗ ) y = x∗y ; ; (∗ a p p l i c a t i o n p a r t i e l l e ∗) let d o u b l e = mul let scale let fun scale f −> ( fun rev x = acc = −> a c c a : : r −> a u x [] k in x) ;; = double scale −> l l e t re c a u x function k = scale x let 2;; ∗( f x +1) 2 10;; | aux rev [1; [] 2; l ;; 3];; ( a : : acc ) r in Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction Programmation fonctionnelle Programmation fonctionnelle Liaison statique Exemples (fonctions6.ml) ( ∗ n e s t une v a r i a b l e l i b r e dans f u n c t i o n x−> x ∗ n ∗ ) I en anglais : let let lexical scoping f multiplier_avec n = f = multiplier_avec function x −> x ∗n ; ; 5;; 3;; I Un identicateur libre (c-à-d qui n'est pas un paramètre) dans une expression fonctionnelle garde la liaison de son occurrence textuelle dans le programme. I On parle d'une clôture (angl. : closure ) I Tous les langages de programmation modernes (fonctionnels ou pas) suivent cette politique. let let let g Introduction Programmation fonctionnelle Des fonctions de première classe dans Java 8 ! g 17;; x = x + m; ; m = (∗ m e s t l i b r e ∗) 42;; (∗ q u e l e s t l e r e s u l t a t ? ∗) 1;; let let let g Programmation Fonctionnelle Avancée m = f x = x + 55;; g y = f f x = x + 1000;; (f y );; 10;; Programmation Fonctionnelle Avancée Introduction Programmation fonctionnelle Des fonctions de première classe dans Python ! Exemple : Appeler une procédure qui prend un ltre en argument (Java 8) : printPersons( roster, (Person p) -> p.getGender() == Person.Sex.MALE && p.getAge() >= 18 && p.getAge() <= 25 ); En Java on est obligé de spécier le type de l'argument. Voir : http://docs.oracle.com/javase/tutorial/java/javaOO/ lambdaexpressions.html from functools import reduce reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) envoie (((1 + 2) + 3) + 4) + 5 = 15. I L'utilisation des lambda en Python est restreinte dû à la distinction entre expressions et instructions. I Pas de typage statique en Python. Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction Programmation fonctionnelle OCaml Des fonctions de première classe dans les maths Le commencement de l'histoire... I Alonzo Church, debut des années 1930 : Lambda Calculus. I Notation : λx.x + 1 I À l'époque utilisé pour l'étude de la fondation des mathématiques I Aujourd'hui : informatique théorique I Voir le cours de Sémantique du M1 Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction OCaml OCaml ... Core ML Histoire d'OCaml I 1973 ML Milner (tactiques de preuves pour le prouveur LCF) Hindley-Milner polymorphic types Damas-Milner type inference I 1980 Projet Formel à l'INRIA (Gérard Huet), Categorical Abstract Machine (Pierre-Louis Curien) I 1984-1990 Dénition de SML (Milner) I 1987 Caml (implémenté en Lisp) Guy Cousineau, Ascander Suarez, (avec Pierre Weis et Michel Mauny) I 1990-1991 Caml Light par Xavier Leroy (et Damien Doligez pour la gestion de la mémoire) First-class functions Algebraic data types Pattern matching I 1995 Caml Special Light puis 1996 OCaml (Xavier Leroy, Jérôme Vouillon, Didier Rémy, Michel Mauny) http://events.inf.ed.ac.uk/Milner2012/X_ Leroy-html5-mp4.html ! Voir Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction OCaml OCaml Traits intéressants du langage Exemples (types.ml) I Les fonctions fournissent un mécanisme d'abstraction puissant. let index = input_line let dict ( open_in " data " ) ; ; I Un système de type polymorphe et implicite qui capture beaucoup d'erreurs. = [ 1 , " one " ; 2 , " two " ] ; ; I La dénition par cas simplie et sécurise l'implémentation I Pas de pointeurs explicites, GC ecace - programmation de très haut niveau. I Évaluation stricte et structures de données mutables. Programmation Fonctionnelle Avancée Li st . assoc index Li st . assoc ( int_of_string Programmation Fonctionnelle Avancée Introduction Introduction OCaml OCaml Exemples (cases.ml) l e t re c d e s t u t t e r match l with | [] | x −> [] y :: rest = y then :: if x else destutter x :: [1; Exemples (mutable.ml) l = let destutter 2; a = a .(0) < − −> destutter 2; dict ;; 3; (y 4];; (y :: :: rest ) rest ) ;; a .(0);; a ;; [|1;2;3|];; 5;; index ) dict ;; Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction OCaml OCaml Inférence de types en OCaml Typage explicite en OCaml I Pas besoin de spécier les types des identicateurs on OCaml I On a le le système trouve le type le plus général. droit de spécier le type des identicateurs (en fait, des expressions quelconques). I Combine concision du code avec la sûreté du typage fort. I Syntaxe : ( <expression> : <type> ) I Java : typage fort (sûr), mais on est obligé de spécier les I Il faut que le type donné soit compatible avec le type trouvé types (lourd). par le compilateur (le même, ou plus restrictif ). I Python : typage dynamique (pendant l'exécution du code). I Il ne s'agit Code concis et élégant, mais on perd en sûreté (erreurs pas d'un mécanisme de conversion de type. apparaissent seulement pendant les tests). Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction OCaml OCaml Exemples (explicit.ml) Pattern matching et dénitions par cas ( ∗ s p e c i f i e r un t y p e ∗ ) let (x : int ) = let triple Une des caractéristiques les plus appréciées des langages de la famille ML comme OCaml est la dénition par cas : 42;; l e t re c x = (x , let triple (x : let triple x = ( x, x );; string ) = (x , (x , x , x) : x, x );; string ∗string∗string ( ∗ pas un mecanisme de c o n v e r s i o n ∗ ) let (x : float ) = 42;; | 0 | n −> −> fact = function 1 n ∗ ( fact (n −1));; est équivalent au code suivant );; l e t re c f a c t n = i f n=0 then 1 e l s e n ∗ ( fact (n −1));; Jusqu'ici, on ne voit pas trop ce qu'on gagne par rapport à faire des conditionnelles en cascade. Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction OCaml OCaml Une dénition par cas résume plusieurs façons de faire des tests Voyons une dénition un peu moins banale : let | f x y = match true , f a l s e | _ | , true false , _ −> −> −> elle peut se traduire comme let if f1 x y 2 else 1 2 3;; 2 else 3;; 1 x y = | | else 3;; match x , y w i t h −> 1 t r u e −> 2 _ −> 3 ; ; true , f a l s e _ , false , f1 x y = then then 2 else 1 then 2 else 3;; l e t f2 x y = i f y then 2 else i f x then 1 else 3;; x if else if 1 l e t f2 x y = i f y then 2 else i f x then f | let if with mais aussi, plus concisément = then i f y then else i f y then x x,y let let let y y t e s t s = [ true , true ; f a l s e , f a l s e ; f a l s e , true ; true , f a l s e ] ; ; test test f ;; test f1 ; ; test f2 ; ; f = L i s t . map ( f u n (x , y) −> f x y) tests ;; Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction OCaml OCaml Les arbres de décision Utilité des arbres de décision I Pour chaque dénition par cas dans le source OCaml, le compilateur doit produire une série de tests qui permettent de Étant donné un arbre de décision associé à une dénition par cas, il déterminer, pour toute donnée en entrée, quelle ligne de la est facile de dénition s'applique. I On peut représenter cette série de tests avec un décision. Sur l'exemple : true rule 2 arbre de I identier les dénitions incomplètes : les cas oubliés sont les branches absentes d'un noeud de décision I identier les dénitions inutiles : si une régle n'apparaît dans aucune feuille, elle ne sera jamais utilisée y false true rule 1 C'est précisément ce qui rend la dénition par cas si utile et x populaire parmi les programmeurs ML : ce n'est false rule 3 pas la même chose qu'une librairie de motif ajoutée au langage comme on peut en trouver pour Scheme ou Java. Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction OCaml OCaml Pointeurs pour aller plus loin La compilation des dénitions par cas ( Quelques résultats pattern matching) a été étudiée depuis les années 1980. Marianne Baudinet and David Macqueen. Tree pattern matching for ml (extended abstract). Technical report, Stanford University, 1985. I Marianne Baudinet et David MacQueen, 1985 : trouver le plus petit arbre de décision est un problème NP-Complet Fabrice Le Fessant and Luc Maranget. I Lefessant et Maranget, 2001 : des heuristiques ecaces pour Optimizing pattern-matching. OCaml (c'est l'algorithme implanté aujourd'hui) In Proceedings of the 2001 International Conference on Functional Programming. ACM Press, 2001. Luc Maranget. Compiling pattern matching to good decision trees. ML'2008. Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction L'environnement de programmation Applications Traits intéressants de l'environnement de programmation Qui utilise OCaml ? un outillage avancé I un toplevel ou REPL (Read-Evaluate-Print Loop) I l'enseignement : ici, par exemple ! I un compilateur bytecode (portable) I la recherche : Coq, Astree, Ocsigen, Mirage, ... I un compilateur natif, très performant I la communauté : Unison, MLDonkey, ... I un compilateur vers JavaScript (js_of_ocaml) I l'industrie : Citrix, Dassault, Esterel, Lexi, Jane Street Capital, OcamlPro, Baretta, Merjis, RedHat, ... I un système de module puissant I une couche objet I des gestionnaires de paquets (en particulier I ... etc. Voyons quelques exemples concrets opam) Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction Applications Applications Operating systems : Citrix, Xen Les outils de gestion de Xen, Operating systems : Mirage l'hyperviseur qui fait fonctionner des millions de machines virtuelles dans le cloud sont écrits en OCaml. OCaml has brought signicant productivity and eciency benets to the project. OCaml has enabled our engineers to be more productive than they would have been had they adopted any of the mainstream languages. Richard Sharp, Citrix David Scott, Richard Sharp, Thomas Gazagnaire and Anil Madhavapeddy. Using functional programming within an industrial product Mirage is an exokernel for constructing secure, high-performance network applications across a variety of cloud computing and mobile platforms. Code can be developed on a normal OS such as Linux or MacOS X, and then compiled into a fully-standalone, specialised microkernel that runs under the Xen hypervisor. Since Xen powers most public cloud computing infrastructure such as Amazon EC2, this lets your servers run more cheaply, securely and ner control than with a full software stack. Mirage is based around the OCaml language ... http: // www. openmirage. org group : perspectives and perceptions. International Conference on Functional Programming, 2010. Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction Applications Applications Social networks : Mylife.com Mylife.com Finance : JaneStreet est un agrégateur de réseaux sociaux écrit en OCaml, avec plusieurs contributeurs, dont Martin Jambon The ocaml language and its libraries oer a good balance between expressiveness and high performance, and we dont have to switch to lower-level languages when we need high performance. Martin Jambon, Mylife.com L'entreprise JaneStreet utilise OCaml pour son activité de trading. Voilà ce que dit Yaron Minsky dans Yaron Minsky. OCaml for the masses. Communications of the ACM, September 2011 Programmation Fonctionnelle Avancée Introduction Applications Concision Our experience with OCaml on the research side convinced us that we could build smaller, simpler, easier-to-understand systems in OCaml than we could in languages such as Java or C#. For an organization that valued readability, this was a huge win. Programmation Fonctionnelle Avancée Introduction Applications Performance We found that OCaml's performance was on par with or better than Java's, and within spitting distance of languages such as C or C++. In addition to having a high-quality code generator, OCaml has an incremental GC (garbage collector). This means the GC can be tuned to do small chunks of work at a time, making it more suitable for soft real-time applications such as electronic trading. Programmation Fonctionnelle Avancée Introduction Applications Bug detection Programmers who are new to OCaml are often taken aback by the degree to which the type system catches bugs. The impression you get is that once you manage to get the typechecker to approve of your code, there are no bugs left. This isn't really true, of course ; OCaml's type system is helpless against many bugs. There is, however, a surprisingly wide swath of bugs against which the type system is eective, including many bugs that are quite hard to get at through testing. Programmation Fonctionnelle Avancée Introduction Applications Pure, mostly Despite how functional programmers often talk about it, mutable state is a fundamental part of programming, and one that cannot and should not be done away with. Sending a network packet or writing to disk are examples of mutability. A complete commitment to immutability is a commitment to never building anything real. Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction Applications Applications Static Analysis : Esterel, Absynthe, Airbus, Facebook ... Il y a désormais des initiatives concrètes pour assurer le support Esterel code generator written in OCaml. Facebook does sophisticated static analysis using OCaml over their vast PHP codebase to close security holes. Airbus, Absynthe use of Astree, written in OCaml, to prevent bugs industriel de OCaml : I OCamlPro est une entreprise de service française dédiée au support I OCamlLabs est une structure non-for-prot qui se consacre au in Airbus code. dévéloppement d'une plateforme OCaml stable Microsoft SLAM and Static Driver Verier Et ils cherchent des personnes qui aiment bien programmer. ... Programmation Fonctionnelle Avancée Programmation Fonctionnelle Avancée Introduction Introduction Programmation Fonctionnelle Avancée Bibliographie Le plan preliminaire du cours I Système de Nouvelles recentes : OCamlLabs et OCamlPro Bibliographie modules avancé privés, interfaces, foncteurs ou modules encapsulation, types paramétrés I Structures de données fonctionnelles ecaces zippers, les, arbres équilibrés I Analyse de coût amorti, raisonnement équationnel innies et paresseuses : ots (streams) Structures de données compactes (hash-consing, memoization) Utilisation avancée du système de types variants polymorphes, GADT Programmation avec combinateurs, DSL, combinateurs pour le I Xavier Leroy et al : The Objective Caml system : documentation and user's manual http://caml.inria.fr I Emmanuel Chailloux, Pascal Manoury et Bruno Pagano : I Structures de données Développement d'Applications avec Objective Caml I O'Reilly, 2000 disponible en ligne I I calcul parallèle I Monades I Chris Okasaki : Purely Functional Data Structures Cambridge University Press, 1998 disponible en ligne