Vue d’ensemble d’Objective Caml Philippe Wang Association des Étudiants en Informatique de Paris 6 27 septembre 2007, 13h - 15h Revision : 1.3 Page Labo Page Perso Site AEIP6 Site OCaml Philippe Wang (AEIP6) : : : : http://www-spiral.lip6.fr/~pwang/ http://philippewang.info/ http://www.aeip6.com http://www.ocaml.org Vue d’ensemble d’Objective Caml 27 septembre 2007 1 / 48 Introduction Avancement dans le plan... Introduction Qu’est-ce qu’Objective Caml ? Présentation du langage Traits impératifs Programmation fonctionnelle Exceptions Modules et Foncteurs Modules Foncteurs Objets Création Héritage Héritage multiple Labels et variants polymorphes Labels Variants polymorphes Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 2 / 48 Introduction Qu’est-ce qu’Objective Caml ? Qu’est-ce qu’Objective Caml ? langage de programmation ? Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 3 / 48 Introduction Qu’est-ce qu’Objective Caml ? Qu’est-ce qu’Objective Caml ? langage de programmation ? I fonctionnel I impératif I modulaire I objets Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 3 / 48 Introduction Qu’est-ce qu’Objective Caml ? Qu’est-ce qu’Objective Caml ? langage de programmation ? I fonctionnel I impératif I modulaire I objets I variants polymorphes, labels, ... Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 3 / 48 Introduction Qu’est-ce qu’Objective Caml ? Objective Caml : qualités et défauts I langage très riche et très expressif, multiparadigme I communauté pas super grande (en comparaison à Java ou Php par exemple) I bibliothèque pas énorme... pas vraiment de standard I performances comparées à celles de C et de C++ I ramasse-miette I typage statique fort par inférence de types I polymorphisme I de très nombreuses extensions I interfaçage avec C, donc indirectement avec la plupart des langages... I ... Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 4 / 48 Introduction Qu’est-ce qu’Objective Caml ? Utilisations Académiques et Industrielles Quelques exemples I enseignement de la programmation très présent en classes préparatoires et dans certaines universités, rare en écoles d’ingénieurs, ... I utilisé dans la recherche en programmation OCaml(INRIA), ocsigen(PPS), astrée(ENS), Lucid Synchrone(LRI) I dans l’industrie (Esterel Technologies (SCADE), XenSource, Dassault Aviation, Jane Street, ...) I I I implantation d’outils pour la certification de programmes (analyses de programmes, compilation) secteur des finances ... Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 5 / 48 Objective Caml C'est du Tonnerre ! Introduction Qu’est-ce qu’Objective Caml ? Quelques pointeurs... I URL de base http://caml.inria.fr/ ou http://ocaml.org/ I Le manuel de référence http://caml.inria.fr/pub/docs/manual-ocaml/ I Accès direct à la documentation de la bibliothèque standard http://caml.inria.fr/pub/docs/manual-ocaml/ libref/index_modules.html I Développement d’Applications avec Objective Caml http://www.pps.jussieu.fr/Livres/ora/DA-OCAML/ (fr) et http://caml.inria.fr/pub/docs/oreilly-book/ (en) I Fruit de travail collaboratif http://www.ocaml-tutorial.org/ (wiki) I ... Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 6 / 48 Présentation du langage Avancement dans le plan... Introduction Qu’est-ce qu’Objective Caml ? Présentation du langage Traits impératifs Programmation fonctionnelle Exceptions Modules et Foncteurs Modules Foncteurs Objets Création Héritage Héritage multiple Labels et variants polymorphes Labels Variants polymorphes Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 7 / 48 Présentation du langage Un langage vraiment Multiparadigme Ce qu’on va voir maintenant... 1. traits impératifs 2. noyau fonctionnel 3. modules et foncteurs 4. objets 5. variants polymorphes 6. labels Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 8 / 48 Présentation du langage Traits impératifs Boucles I I I for plop = 42 / 23 to 42 * 23 + 1 do print_string "Itération numéro " ; print_int i ; print_char ’n’ done for plop = 23 downto 0 do print_string "Itération numéro " ; print_int i ; print_char ’n’ done let x = ref 0 in while !x < 42 do print_int !x; x := !x + 1 done Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 9 / 48 Présentation du langage Traits impératifs Variables et Affectations En fonctionnel pur, les valeurs sont immutables... En OCaml, rien n’est « implicitement mutable » ! I type ’a ref = { mutable contents : ’a ; } I let ( := ) a b = a.contents <- b I let ( ! ) a = a.contents I let a = ref 0 ;; a := !a * 42 ;; Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 10 / 48 Présentation du langage Traits impératifs Variables et Affectations En fonctionnel pur, les valeurs sont immutables... En OCaml, rien n’est « implicitement mutable » ! I type ’a ref = { mutable contents : ’a ; } I let ( := ) a b = a.contents <- b val ( := ) : ’a ref -> ’a -> unit = <fun> I let ( ! ) a = a.contents val ( ! ) : ’a ref -> ’a = <fun> I let a = ref 0 ;; val a : int ref = {contents = 0} a := !a * 42 ;; - : unit = () Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 10 / 48 Présentation du langage Traits impératifs Déclarations de types Que peut représenter le type suivant ? type ’a t mutable mutable mutable } = { value : ’a ; next : ’a t ; previous : ’a t Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 11 / 48 Présentation du langage Traits impératifs Déclarations de types On peut faire mieux ! type ’a option = None | Some of ’a type ’a t mutable mutable mutable } = { value : ’a ; next : ’a t ; previous : ’a t Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 12 / 48 Présentation du langage Traits impératifs Déclarations de types On fait mieux ! type ’a option = None | Some of ’a type ’a t mutable mutable mutable } = { value : ’a ; next : ’a t option ; previous : ’a t option Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 12 / 48 Présentation du langage Traits impératifs Sauvons les arbres ! Un arbre en Caml ? type | | | ’a tree = Empty Leaf of ’a (* <- peut être omis *) Node of ’a * ’a tree * ’a tree Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 13 / 48 Présentation du langage Traits impératifs Sauvons les arbres ! Un arbre en Caml ? type ’a tree = | Empty | Node of ’a * ’a tree * ’a tree Par rapport à la représentation précédente : I allourdissement des données (de peu) I allègement de la représentation (de peu) I facilite les comparaisons entre deux arbres (de beaucoup) Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 13 / 48 Présentation du langage Traits impératifs Sauvons les arbres ! Et animons leurs vies ! Se balader (de bas en haut et de haut en bas) sur un arbre ? type (* (* (* (* } ’a node mutable mutable mutable mutable = { *) value *) parent *) left *) right : : : : ’a ’a ’a ’a ; tree option ; tree ; tree ; type ’a tree = | Empty | Node of ’a node on peut enlever option pour optimiser, mais avoir un parent égal à une feuille vide peut paraître “bizarre” Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 14 / 48 Présentation du langage Programmation fonctionnelle Et les listes ? Les listes sont super utiles, surtout quand on peut les utiliser facilement... type ’a list = Nil | Cons of ’a * ’a list ... Cons(value | pointer) Cons(value | pointer) Philippe Wang (AEIP6) Nil Cons(value | pointer) Vue d’ensemble d’Objective Caml 27 septembre 2007 15 / 48 Présentation du langage Programmation fonctionnelle Programmation fonctionnelle type ’a list = Nil | Cons of ’a * ’a list let rec map f l = match l with | Nil -> Nil | Cons(hd, tl) -> Cons(f hd, map f tl) let l1 = Cons(1, Cons(2, Cons(3,Nil))) let l2 = map (fun n -> n + 1) l1 Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 16 / 48 Présentation du langage Programmation fonctionnelle Les listes « natives » du langage type ’a list = [] | :: of ’a * ’a list let rec map f l = match l with | Nil -> Nil | Cons(hd, tl) -> Cons(f hd, map f tl) let rec map f l = match l with | [] -> [] | hd :: tl -> f hd :: map f tl let rec map f = function | [] -> [] | hd :: tl -> f hd :: map f tl exercice : renommer le type list utilisateur en listb et écrire la fonction de conversion list_of_listb de type listb -> list Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 17 / 48 Présentation du langage Programmation fonctionnelle Utilisation de map let l3 = [ 23 ; 37 ; 42 ; 69 ] ;; let l4 = map string_of_int l3 ;; Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 18 / 48 Présentation du langage Programmation fonctionnelle Utilisation de map let l3 = [ 23 ; 37 ; 42 ; 69 ] ;; val l3 : int list = [23; 37; 42; 69] let l4 = map string_of_int l3 ;; val l4 : string list = ["23"; "37"; "42"; "69"] Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 18 / 48 Présentation du langage Programmation fonctionnelle Il pleut des factorielles ! let rec fact n = if n = 0 then 1 else n * fact (n - 1) let fact n = let rec aux accu n = if n = 0 then accu else aux (accu*n) (n-1) in aux 1 n exercice : donner une ou deux autres implantations de la fonction factorielle Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 19 / 48 Présentation du langage Exceptions Boucles et Exceptions (1) Will you let this cat catch a cold ? let nude_cat () = try while true do print_char (read_char ()) done with End_of_file -> () Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 20 / 48 Présentation du langage Exceptions Boucles et Exceptions (2) Compteur de lignes... let count_lines () = let i = ref 0 in try while true do ignore (read_line ()); incr i done with End_of_file -> Printf.printf "I’ve counted %d lines" !i Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 21 / 48 Présentation du langage Exceptions Boucles et Exceptions (3) Give some cloths to the cat ! let cat () = let argc = Array.length Sys.argv in if argc = 1 then nude_cat () else for i = 1 to argc - 1 do let file = open_in Sys.argv.(i) in try while true do print_char (input_char file) done with End_of_file -> () done Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 22 / 48 Présentation du langage Exceptions Boucles et Exceptions (4) Give some prettier cloths to the cat ! let cat () = match Array.length Sys.argv with | 0 -> nude_cat () | argc -> for i = 0 to argc - 1 do let file = open_in Sys.argv.(i) in try while true do print_char (input_char file) done with End_of_file -> () done Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 23 / 48 Présentation du langage Exceptions Exceptions et style fonctionnel let rec assoc elem list = match list with | [] -> raise Not_found | (e, a) :: tl -> if elem = e then a else assoc elem tl let rec assoc elem = function | [] -> raise Not_found | (e, a) :: tl -> if elem = e then a else assoc elem tl Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 24 / 48 Présentation du langage Exceptions Style fonctionnel pur (donc sans exception) let rec assoc_ter elem = function | [] -> None | e::tl -> if e = elem then Some e else assoc_ter elem tl Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 25 / 48 Présentation du langage Exceptions Démonstrations et Exemples Utilisations de Filtrages par motifs (pattern matching) I destructuration des données en profondeur Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 26 / 48 Présentation du langage Exceptions Fonctionnel versus Impératif Impératif I plus efficace ? I plus proche du modèle de fonctionnement des processeurs généralistes I effets de bords souvent dangereux I plus facile à comprendre car moins riche ? Fonctionnel I plus « propre », plus expressif I plus facile pour les débutants en programmation qui ont des bases en mathématiques ? Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 27 / 48 Présentation du langage Exceptions Fonctionnel versus Impératif Les modèles I machines de Turing, λ -calcul, machines à registres illimités, ... Les langages hybrides I ml, lisp/scheme, ... Les langages purs I Haskell, ... Applications I en général, on utilise des styles hybrides Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 27 / 48 Modules et Foncteurs Avancement dans le plan... Introduction Qu’est-ce qu’Objective Caml ? Présentation du langage Traits impératifs Programmation fonctionnelle Exceptions Modules et Foncteurs Modules Foncteurs Objets Création Héritage Héritage multiple Labels et variants polymorphes Labels Variants polymorphes Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 28 / 48 Modules et Foncteurs Modules Modules quelques mot-clefs : module, struct, end, open, include, sig, let .. in module ModuleName = struct type t = A | B | C let f = function A -> 1 | B -> 2 | C -> 42 end signature : module ModuleName : sig type t = A | B | C val f : t -> int end Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 29 / 48 Modules et Foncteurs Modules Modules : open et include module M = struct type t = A end let x = M.A open M let y = A y = M.A : M.t module M = struct type t = A end let x = M.A include M let y = A y=A:t Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 30 / 48 Modules et Foncteurs Modules Démonstrations et Exemples Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 31 / 48 Modules et Foncteurs Foncteurs Foncteurs Un mot-clef en plus : functor. Pour... des modules qui prennent d’autres modules en paramètres... Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 32 / 48 Modules et Foncteurs Foncteurs L’histoire du point coloré... module type Point = sig type point val get_x : point -> int val get_y : point -> int end module Color_point = functor (P:Point) -> struct type colored_point = { color : int ; point : P.point } let get_x p = P.get_x p.point let get_y p = P.get_y p.point end Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 33 / 48 Modules et Foncteurs Foncteurs Héritage ou vol ? ou emprunt ? module type Point = sig type point val get_x : point -> int val get_y : point -> int end module Color_point = functor (P:Point) -> struct include P type colored_point = { color : int ; point : point } let get_x p = get_x p.point let get_y p = get_y p.point end Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 34 / 48 Modules et Foncteurs Foncteurs Syntaxe plus compacte module type Point = sig type point val get_x : point -> int val get_y : point -> int end module Color_point (P:Point) = struct include P type colored_point = { color : int ; point : point } let get_x p = get_x p.point let get_y p = get_y p.point end Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 35 / 48 Modules et Foncteurs Foncteurs Démonstration d’exemples d’utilisation I modules Set et module Map de la bibliothèque standard Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 36 / 48 Objets Avancement dans le plan... Introduction Qu’est-ce qu’Objective Caml ? Présentation du langage Traits impératifs Programmation fonctionnelle Exceptions Modules et Foncteurs Modules Foncteurs Objets Création Héritage Héritage multiple Labels et variants polymorphes Labels Variants polymorphes Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 37 / 48 Objets Création Le Point sur un axe... La classe class point = object val mutable x = 0 method get_x = x method move d = x <- x + d end Sa signature class point : object val mutable x : int method get_x : int method move : int -> unit end Création d’un point let p = new point val p : point = <obj> Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 38 / 48 Objets Création Évaluation dans le top-level p#get_x ;; - : int = 0 p#move 3 ;; - : unit = () p#get_x ;; - : int = 3 Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 39 / 48 Objets Création Histoires d’ingénierie... I les champs des objets sont privés (accessibles uniquement par les méthodes de la classe) et en lecture seule I ils peuvent néanmoins être déclarés comme étant mutables I les méthodes sont publiques I la valeur d’un champ peut être une fonction, mais attention : la fonction n’a pas accès aux champs puisqu’elle n’est pas une méthode de la classe I ... Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 40 / 48 Objets Héritage Histoires d’héritages... class p ((x,y):int*int) = object val x = x val y = y method get_x = x method get_y = y end class cp (x,y) (color : int) = object (self) inherit p(x,y) val c = color method color = c end Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 41 / 48 Objets Héritage multiple Héritage multiple class c (color:int) = object val c = color method color = c end class p ((x,y):int*int) = object val x = x val y = y method get_x = x method get_y = y end class cp (x,y) color = object (self) inherit p(x,y) inherit c color end Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 42 / 48 Objets Héritage multiple Le polymorphisme chez les objets cf. ressources indiquées plus haut, ou bien cours de Typage et Polymorphisme (M2 STL)1 1 http://www-spiral.lip6.fr/~chaillou/Public/enseignement/2006-2007/tep/ Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 43 / 48 Labels et variants polymorphes Avancement dans le plan... Introduction Qu’est-ce qu’Objective Caml ? Présentation du langage Traits impératifs Programmation fonctionnelle Exceptions Modules et Foncteurs Modules Foncteurs Objets Création Héritage Héritage multiple Labels et variants polymorphes Labels Variants polymorphes Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 44 / 48 Labels et variants polymorphes Labels Labels : arguments étiquetés sans valeurs par défaut # let f ~x:x1 ~y:y1 = x1 - y1;; val f : x:int -> y:int -> int = <fun> # f ~x:3 ~y:2;; - : int = 1 # f ~y:2 ~x:11;; - : int = 9 Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 45 / 48 Labels et variants polymorphes Labels Labels : arguments étiquetés avec valeurs par défaut # let print ?(msg = "") i = print_int i ;; val print : ?msg:string -> int -> unit = <fun> # let () = print 42;; 42 # let () = print "hello" 42;; Expecting function has type ?msg:string -> unit This argument cannot be applied without label # let () = print ~msg:"hello" 42;; 42 Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 46 / 48 Labels et variants polymorphes Variants polymorphes Variants polymorphes Des constructeurs de types sommes libertins créés à la volée... # let print = function ‘Int i -> print_int i;; # let print = function ‘Int i -> print_int i | ‘Float f -> print_float f ;; # let print = function | ‘String s -> print_string s | v -> print v;; # let print = function ‘String s -> print_string s | (‘Float _ | ‘Int _) as v -> print v ;; Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 47 / 48 Labels et variants polymorphes Variants polymorphes Des... Questions ? Philippe Wang (AEIP6) Vue d’ensemble d’Objective Caml 27 septembre 2007 48 / 48