slides-cours-caml

Publié par

pourquoi ce cours?Master d’Informatique M1 – Universit´e Paris SudMise `a niveau programmation CamlInitiation `a la Caml utilis´eprogrammation fonctionnelle Cours de compilation : TD, examensProjet de compilation : ´ecriture d’un compilateur en Caml`A faire :Sylvain Conchon lire le poly de ce courslire le poly Formation au langage Caml et faire les exercices13 Septembre 2007() 13 Septembre 2007 1 / 105 () 13 Septembre 2007 2 / 105rappelPremiers pas en Camlil n’y a pas de bon langage, il n’y a que de bons programmeurs`a lire : La programmation en pratique de Brian W. Kernighan & RobertPike() 13 Septembre 2007 3 / 105 () 13 Septembre 2007 4 / 105le premier programme d´eclarationshello.mlprint string "hello world!\n" programme = suite de d´eclarations et d’expressions `a ´evaluerCompilation let x = 1 + 2;;% ocamlc -o hello hello.ml print int x;;let y = x * x;;print int y;;Ex´ecution% ./hellohello world!() 13 Septembre 2007 5 / 105 () 13 Septembre 2007 6 / 105notion de variable r´ef´erenceslet x = e introduit une variable globale Une variable modifiable s’appelle une r´ef´erenceElle est introduite avec refDiff´erences avec la notion usuelle de variable :let x = ref 1;;1 n´ecessairement initialis´ee print int !x;;2 x := !x + 1;;type pas d´eclar´e mais inf´er´eprint int !x;;3 contenu non modifiable() 13 Septembre 2007 7 / 105 () 13 Septembre 2007 8 / 105expressions et instructions type unitpas de distinction expression/instruction dans la ...
Publié le : samedi 24 septembre 2011
Lecture(s) : 47
Nombre de pages : 27
Voir plus Voir moins

pourquoi ce cours?
Master d’Informatique M1 – Universit´e Paris Sud
Mise `a niveau programmation Caml
Initiation `a la Caml utilis´e
programmation fonctionnelle Cours de compilation : TD, examens
Projet de compilation : ´ecriture d’un compilateur en Caml
`A faire :
Sylvain Conchon lire le poly de ce cours
lire le poly Formation au langage Caml et faire les exercices
13 Septembre 2007
() 13 Septembre 2007 1 / 105 () 13 Septembre 2007 2 / 105
rappel
Premiers pas en Caml
il n’y a pas de bon langage, il n’y a que de bons programmeurs
`a lire : La programmation en pratique de Brian W. Kernighan & Robert
Pike
() 13 Septembre 2007 3 / 105 () 13 Septembre 2007 4 / 105le premier programme d´eclarations
hello.ml
print string "hello world!\n" programme = suite de d´eclarations et d’expressions `a ´evaluer
Compilation let x = 1 + 2;;
% ocamlc -o hello hello.ml print int x;;
let y = x * x;;
print int y;;Ex´ecution
% ./hello
hello world!
() 13 Septembre 2007 5 / 105 () 13 Septembre 2007 6 / 105
notion de variable r´ef´erences
let x = e introduit une variable globale Une variable modifiable s’appelle une r´ef´erence
Elle est introduite avec ref
Diff´erences avec la notion usuelle de variable :
let x = ref 1;;
1 n´ecessairement initialis´ee print int !x;;
2 x := !x + 1;;type pas d´eclar´e mais inf´er´e
print int !x;;3 contenu non modifiable
() 13 Septembre 2007 7 / 105 () 13 Septembre 2007 8 / 105expressions et instructions type unit
pas de distinction expression/instruction dans la syntaxe : que des
les expressions sans r´eelle valeur (affectation, boucle, ...) ont pour type
expressions
unit
constructions usuelles :
ce type a une unique valeur, not´ee ()
conditionnelle c’est le type donn´e `a la branche else lorsqu’elle est absente
if i = 1 then 2 else 3
correct :
boucle for
if !x > 0 then x := 0
for i = 1 to 10 do x := !x + i done
incorrect :s´equence
2 + (if !x > 0 then 1)
x := 1; 2 * !x
() 13 Septembre 2007 9 / 105 () 13 Septembre 2007 10 / 105
variables locales let in = expression
En C ou Java, la port´ee d’une variable locale est d´efinie par le bloc :
{
int x = 1;
... let x = e1 in e2 est une expression
} son type et sa valeur sont ceux de e2,
dans un environnement ou` x a le type et la valeur de e1
En Caml, variable locale introduite par let in :
let x = 10 in x * x
Exemple
Comme une variable globale : let x = 1 in (let y = 2 in x + y) * (let z = 3 in x * z)
n´ecessairement initialis´ee
type inf´er´e
immuable
mais port´ee limit´ee `a l’expression qui suit le in
() 13 Septembre 2007 11 / 105 () 13 Septembre 2007 12 / 105parall`ele r´ecapitulation
Java Caml programme = suite d’expressions et de d´eclarations
{ int x = 1; let x = ref 1 in variables introduites par le mot cl´e let non modifiables
x = x + 1; x :=!x + 1;
pas de distinction expression / instruction
int y = x * x; let y =!x *!x in
System.out.print(y); } print int y
() 13 Septembre 2007 13 / 105 () 13 Septembre 2007 14 / 105
la boucle d’interaction
version interactive du compilateur
% ocaml
FonctionsObjective Caml version 3.09.1
# let x = 1 in x + 2;;
- : int = 3
# let y = 1 + 2;;
val y : int = 3
# y * y;;
- : int = 9
() 13 Septembre 2007 15 / 105 () 13 Septembre 2007 16 / 105syntaxe proc´edure
une proc´edure = une fonction dont le r´esultat est de type unit
# let f x = x * x;;
Exemple
val f : int -> int = <fun>
# let x = ref 1;;
corps = expression (pas de return) # let set v = x := v;;
type inf´er´e (types de l’argument x et du r´esultat) val set : int -> unit = <fun>
# set 3;;
# f 4;;
- : unit = ()
- : int = 16
# !x;;
- : int = 3
() 13 Septembre 2007 17 / 105 () 13 Septembre 2007 18 / 105
fonction “sans argument” fonction `a plusieurs arguments
prend un argument de type unit
# let f x y z = if x > 0 then y + x else z - x;;
Exemple
val f : int -> int -> int -> int = <fun>
# let reset () = x := 0;;
# f 1 2 3;;
val reset : unit -> unit = <fun>
- : int = 3
# reset ();;
() 13 Septembre 2007 19 / 105 () 13 Septembre 2007 20 / 105fonction locale fonction comme valeur de premi`ere classe
fonction = expression comme une autre, introduite par fun
# fun x -> x+1
fonction locale `a une expression
- : int -> int = <fun>
# let carre x = x * x in carre 3 + carre 4 = carre 5;;
- : bool = true # (fun x -> x+1) 3;;
- : int = 4
fonction locale `a une autre fonction
# let pythagore x y z =
En r´ealit´e
let carre n = n*n in carre x + carre y = carre z;;
let f x = x+1;;
val pythagore : int -> int -> int -> bool = <fun> est la mˆeme chose que
let f = fun x -> x+1;;
() 13 Septembre 2007 21 / 105 () 13 Septembre 2007 22 / 105
application partielle application partielle (suite)
fun x y -> x*x + y*y
est la mˆeme chose que
fun x -> fun y -> x*x + y*y
l’application partielle est une mani`ere de retourner une fonctionon peut appliquer une fonction partiellement
mais on peut aussi retourner une fonction `a l’issue d’un calcul
Exemple # let f x = let x2 = x * x in fun y -> x2 + y * y;;
# let f x y = x*x + y*y;;
val f : int -> int -> int = <fun>
val f : int -> int -> int = <fun>
une application partielle de f ne calcule x*x qu’une seule fois
# let g = f 3;;
val g : int -> int = <fun>
# g 4;;
- : int = 25
() 13 Septembre 2007 23 / 105 () 13 Septembre 2007 24 / 105application partielle : exemple ordre sup´erieur
une fonction peut prendre des fonctions en arguments
# let compteur depuis n = # let int`egre f =
let r = ref (n-1) in fun () -> incr r; !r;; let n = 100 in
let s = ref 0.0 inval compteur depuis : int -> unit -> int = <fun>
for i = 0 to n do# let c = compteur depuis 0;;
let x = float i /. float n in s := !s +. f x
val c : unit -> int = <fun>
done;
# c ();;
!s /. float n
- : int = 0
# int`egre sin;;
# c ();;
- : float = 0.463901218235397317
- : int = 1
# int`egre (fun x -> x*.x);;
- : float = 0.33835
() 13 Septembre 2007 25 / 105 () 13 Septembre 2007 26 / 105
it´erateurs it´erateurs sur les listes : iter et map
En Java on it`ere ainsi sur les ´el´ements d’une structure de donn´ees
for (Enumeration e = v.elements() ; e.hasMoreElements() ;) {
iter : (’a -> unit) -> ’a list -> unit
... on traite e.nextElement() ...
}
iter f [a1; ...; an]} = f a1; ... ; f an
En Caml, it´erateur = fonction d’ordre sup´erieur
map : (’a -> ’b) -> ’a list -> ’b list
Exemple : table associant des chaˆınes de caract`eres
map f [a1; ...; an] = [b1; ...; bn]val iter : (string -> string -> unit) -> table -> unit
let n = ref 0 in iter (fun x y -> incr n) t; !n
iter (fun x y -> Printf.printf "%s -> %s\n" x y) t
() 13 Septembre 2007 27 / 105 () 13 Septembre 2007 28 / 105it´erateurs sur les listes : fold left diff´erence avec les pointeurs de fonctions
fold left : (’a -> ’b -> ’a) -> ’a -> ’b list -> ’a
fold left f a [b1; ...; bn] = f (...(f (f a b1) b2)...) bn “en C aussi on peut passer et retourner des fonctions par l’interm´ediaire de
pointeurs de fonctions”
Exemple
let partition p l = mais les fonctions d’ocaml sont plus que des pointeurs de fonctions
List.fold left let f x = let x2 = x * x in fun y -> x2 + y * y;;
(fun (ok,ko) x ->
if p x then (x::ok,ko) else (ok,x::ko)) ([],[]) l
() 13 Septembre 2007 29 / 105 () 13 Septembre 2007 30 / 105
fonctions r´ecursives polymorphisme
# let f x = x;;
En Caml, le recours aux fonctions r´ecursives est naturel, car
val f : ’a -> ’a = <fun>
un appel de fonction ne couteˆ pas cher # f 3;;
la r´ecursivit´e terminale est correctement compil´ee - : int = 3
# f true;;Exemple :
- : bool = truelet z´ero f =
# f print int;;let rec cherche i = if f i = 0 then i else cherche (i+1) in
cherche 0 - : int -> unit = <fun>
# f print int 1;;
code r´ecursif ⇒ plus lisible, plus simple `a justifier
1- : unit = ()
() 13 Septembre 2007 31 / 105 () 13 Septembre 2007 32 / 105polymorphisme (suite) r´ecapitulation
fonctions = valeurs comme les autres : locales, anonymes, arguments
Caml inf`ere toujours le type le plus g´en´eral possible
d’autres fonctions, etc.
Exemple :
partiellement appliqu´ees# let compose f g = fun x -> f (g x);;
polymorphesval : (’a -> ’b) -> (’c -> ’a) -> ’c -> ’b = <fun>
l’appel de fonction ne couteˆ pas cher
() 13 Septembre 2007 33 / 105 () 13 Septembre 2007 34 / 105
GC
allocation m´emoire r´ealis´ee par un garbage collector (GC)Allocation m´emoire
Int´erˆets :
r´ecup´eration automatique
allocation efficace
⇒ perdre le r´eflexe ( allouer couteˆ cher )
... mais continuer `a se soucier de complexit´e!
() 13 Septembre 2007 35 / 105 () 13 Septembre 2007 36 / 105tableaux tri par insertion
let tri insertion a =# let a = Array.create 10 0;;
let swap i j = let t = a.(i) in a.(i) <- a.(j); a.(j) <- t inval a : int array = [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]
for i = 1 to Array.length a - 1 don´ecessairement initialis´e
(* ins´ erer l’´ el´ement i dans 0..i-1 *)
# let a = [| 1; 2; 3; 4 |];;
let j = ref (i - 1) in
# a.(1) <- 5;;
while !j >= 0 && a.(!j) > a.(!j + 1) do
- : unit = () swap !j (!j + 1); decr j
# a;; done
- : int array = [|1; 5; 3; 4|] done
() 13 Septembre 2007 37 / 105 () 13 Septembre 2007 38 / 105
tri par insertion enregistrements
let tri insertion a =
comme les records de Pascal ou les structures de C
let swap i j = let t = a.(i) in a.(i) <- a.(j); a.(j) <- t in on d´eclare le type enregistrement
for i = 1 to Array.length a - 1 do
type complexe = { re : float; im : float }
(* ins´erer l’´el´ement i dans 0..i-1 *)
let rec ins`ere j = allocation et initialisation simultan´ees :
if j >= 0 && a.(j) > a.(j+1) then # let x = { re = 1.0; im = -1.0 };;
begin swap j (j+1); ins` ere (j-1) end
val x : complexe = {re = 1.; im = -1.}
in
# x.im;;ins`ere (i-1)
- : float = -1.done
() 13 Septembre 2007 39 / 105 () 13 Septembre 2007 40 / 105

Soyez le premier à déposer un commentaire !

17/1000 caractères maximum.