chapitre 0 : le langage caml -...

43
Chapitre 0 : Le langage Caml 1/30

Upload: lenga

Post on 13-Sep-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

Chapitre 0 : Le langage Caml

1/30

Programmation impérative versus fonctionnelle

Prog. impérativeséquences d’instructions ;notion d’état du programme ;boucles for et while essentielles.les processeurs sont de nature impérative : exécutions d’instructionsdonnées par « op codes ».état du programme : contenu de la mémoire à chaque instant.Python, C, Assembleur, Langage machine : plus ou moins hautniveaux, mais tous impératifs.

2/30

Programmation impérative versus fonctionnelle

Prog. fonctionnelleautre paradigme de programmation ;un programme est une fonction mathématique ;exécution du programme : évaluation de la fonction ;Eviter la notion d’état, d’effet de bord : un calcul donne toujours lemême résultat (c.ex : fonction de tri en Python)la récursivité (appel d’une fonction à elle même) remplace lesboucles.

3/30

Exemple : la factorielle

Factorielle impérative

Fonction fact(n)f ← 1;pour i allant de 1 à n faire faire

f ← f × ifinRenvoyer f

Factorielle fonctionnelle

Fonction fact(n)si n ≥ 0 alors

Renvoyer 1sinon

Renvoyer n × fact(n − 1)fin

4/30

Python versus Caml

PythonLangage impératif, permettant l’usage de la récursivité.

CamlLangage fonctionnel, permettant la programmation impérative.

5/30

Introduction à Caml

Un langage fortement typé; présentation de l’interpréteur : 4+1 ;;

Caml : fortement typé.un calcul Caml termine par ;;

Caml procède (avant l’évaluation) par une analyse de type.Mélange des genres interdit !notion de polymorphisme (exemple : max).

avantages/inconvénientsplus dur d’écrire des choses fausses ;un peu plus long à écrire que Python.

6/30

Types simples

Unittype unit

équivalent du None de Python. Une seule valeur : ().

# () ;;- : unit = ()

Entierstype int

sur 64 bits, plage de valeurs [[−262, 262 − 1]].opérateurs usuels : +, *, -, / (division entière) et mod (modulo).

# 2*16 ;;- : int = 32# 58 mod 14 ;;- : int = 2

7/30

Types simples

Flottantstype float ;semblables à ceux de Python ;opérateurs simples : les mêmes que pour les entiers (sauf mod qui n’apas d’équivalent), mais suivis d’un point : +., /., -., *. ;fonctions usuelles (cos, sin, exp, atan...) définies sur les flottants ;exponentiation (**).

# 2.0 *. 8.9 ;;- : float = 17.8# 2.0 ** 8.9 ;;- : float = 477.712891667# cos 5. ;;- : float = 0.283662185463

8/30

Types simples

Pas de mélanges !# 2 * 3.0 ;;Toplevel input:>2 * 3.0 ;;> ^^^This expression has type float,but is used with type int.# 2 ** 5 ;;Toplevel input:>2 ** 5 ;;>^This expression has type int,but is used with type float.

9/30

Types simples

Booléenstype bool ;deux constantes : true et false ;opérateurs : && (et logique), || (ou logique, la barre s’obtient avecAlt gr + 6) et not (non logique).

# true && false ;;- : bool = false# false || true ;;- : bool = true# not true ;;- : bool = false

paresseux, comme en Python :# false && 1/0>0 ;;- : bool = false# true || 1/0>0 ;;- : bool = true

10/30

Déclarations

Déclaration « globale »let x= ... ;; pour déclarer une variable.plutôt une constante...

# let x = 4 ;;x : int = 4

Déclaration « locale »let x= ... in ... ;; pour déclarer une variable localement.si x déja liée, valeur précédente oubliée (temporairement) ;affectation locale à ce qui suit in ;

# let x= 5.**0.25 in x +. x *. x +. x ** 3. ;;- : float = 7.0751182836# x ;;- : int = 4

11/30

Déclarations

Déclaration « simultanée »let x= ... and y= ... ;; pour déclarer deux variablessimultanément ;compatible avec in ;

# let x=0 and y=1 ;;x : int = 0y : int = 1# let x=0 and y=1 in x+y ;;- : int = 1

ne pas confondre locale et simultanée.

# let x=0 and y=x+2 in x+y ;;Toplevel input:>let x=0 and y=x+2 in x+y ;;> ^The value identifier x is unbound.

12/30

Déclarations : références

Référencesvariables Caml : liaison d’un nom et d’une valeur ;référence : « pointeur » vers une case mémoire dont on peut lire etécrire le contenu ;la « valeur » de la référence est une adresse mémoire (fixée)la valeur « pointée » par la référence est modifiablesyntaxe : ref valeur pour créer une référence pointant initialementvers valeur.type t ref, où t est le type de la valeur.typique de la programmation impérative !

# let r= ref 0 ;;r : int ref = ref 0

13/30

Déclarations : références

Déférencement, modificationvaleur pointée par une référence !r ;modifier la valeur : r := x.

# let x= ref 0 ;;x : int ref = ref 0# x:= !x + 1 ;;- : unit = ()# !x ;;- : int = 1

14/30

Types plus complexes

Tuplesn-uplettype : produit cartésien des typessyntaxe : parenthèses facultatives et virgules

# (true, 0, atan 1.0) ;;- : bool * int * float = true, 0, 0.785398163397

déconstruction : let a,b,... = t

# let a,b=(0, 1.0) ;;a : int = 0b : float = 1.0

fst et snd : renvoie première et deuxième composante d’un couple.# fst (1, 5.0) ;;- : int = 1# snd (4, true) ;;- : bool = true

15/30

Types plus complexes

Tableauxtaille fixée à la création : immuable ;homogène !type t vect où t est le type des éléments.# [|5; 0; 7|] ;;- : int vect = [|5; 0; 7|]# [|(2,1) ; (5,7)|] ;;- : (int * int) vect = [|2, 1; 5, 7|]

si n la taille, t.(0), ..., t.(n-1) : accès aux éléments ;modification : t.(i) <- x# let t = [|0; 5; 7|] ;;t : int vect = [|0; 5; 7|]# t.(0) <- 2 ;;- : unit = ()# t ;;- : int vect = [|2; 5; 7|]

programmation impérative !

16/30

Types plus complexes

Chaînes de caractèrestype string

très similaire à des char vect

accès/modification : s.[i]

attention : char 6= string.# let s = "abc" ;;s : string = "abc"# s.[0] ;;- : char = `a`# s.[0] <- `d` ;;- : unit = ()# s ;;- : string = "dbc"

17/30

Fonctions

Quelques exemples# int_of_float ;;- : float -> int = <fun># int_of_float (3.5) ;;- : int = 3# fst ;;- : 'a * 'b -> 'a = <fun># fst (true, 5.4) ;;- : bool = true

Fonctionsune fonction est une valeurtype : t1 -> t2 ;

18/30

Fonctions

Quelques exemples# int_of_float ;;- : float -> int = <fun># int_of_float (3.5) ;;- : int = 3# fst ;;- : 'a * 'b -> 'a = <fun># fst (true, 5.4) ;;- : bool = true

Fonctionsune fonction est une valeurtype : t1 -> t2 ;

18/30

Fonctions à un seul argument. Appel

Syntaxefunction variable -> expression

types de la variable et de l’expression détectés automatiquement# function x -> x+1 ;;

- : int -> int = <fun>

Appelcomme en mathématiques : f (x) ;en fait les parenthèses sont facultatives : f x.x de type t1 et f de type t1 -> t2 alors f x de type t2.polymorphisme !

Exemples# (function x -> x +. 1.) 2. ;;- : float = 3.0# let f = function x -> x+1 in f 5 ;;- : int = 6

19/30

Fonctions à un seul argument + liaison

SyntaxePour déclarer et lier une fonction à une variable ;let f x = expression

Exemple 1# let f x = x+1 ;;f : int -> int = <fun># f 5 ;;- : int = 6

Exemple 2 : fonction sur un couple# let f (x,y) = x+y ;;f : int * int -> int = <fun># f (0, 2) ;;- : int = 2

20/30

Fonctions à un seul argument + liaison

SyntaxePour déclarer et lier une fonction à une variable ;let f x = expression

Exemple 1# let f x = x+1 ;;f : int -> int = <fun># f 5 ;;- : int = 6

Exemple 2 : fonction sur un couple# let f (x,y) = x+y ;;f : int * int -> int = <fun># f (0, 2) ;;- : int = 2

20/30

Fonctions à un seul argument + liaison

SyntaxePour déclarer et lier une fonction à une variable ;let f x = expression

Exemple 1# let f x = x+1 ;;f : int -> int = <fun># f 5 ;;- : int = 6

Exemple 2 : fonction sur un couple# let f (x,y) = x+y ;;f : int * int -> int = <fun># f (0, 2) ;;- : int = 2

20/30

Fonctions à un seul argument + liaison

Exemple 3 : polymorphisme# let f (x,y) = (y, x) ;;f : 'a * 'b -> 'b * 'a = <fun># f (2, 3.0) ;;- : float * int = 3.0, 2

Exemple 4 : avec déclaration locale# let f x = let y= exp x in (y+. 1.0/. y)/. 2. ;;f : float -> float = <fun># f 1.0 ;;- : float = 1.54308063482

Exemple 5 : déclaration simultanée# let ch x = let y= exp x in (y+. 1.0/. y)/. 2.

and sh x = let y= exp x in (y-. 1.0/. y)/. 2.;;ch : float -> float = <fun>sh : float -> float = <fun>

21/30

Fonctions à un seul argument + liaison

Exemple 3 : polymorphisme# let f (x,y) = (y, x) ;;f : 'a * 'b -> 'b * 'a = <fun># f (2, 3.0) ;;- : float * int = 3.0, 2

Exemple 4 : avec déclaration locale# let f x = let y= exp x in (y+. 1.0/. y)/. 2. ;;f : float -> float = <fun># f 1.0 ;;- : float = 1.54308063482

Exemple 5 : déclaration simultanée# let ch x = let y= exp x in (y+. 1.0/. y)/. 2.

and sh x = let y= exp x in (y-. 1.0/. y)/. 2.;;ch : float -> float = <fun>sh : float -> float = <fun>

21/30

Fonctions à un seul argument + liaison

Exemple 3 : polymorphisme# let f (x,y) = (y, x) ;;f : 'a * 'b -> 'b * 'a = <fun># f (2, 3.0) ;;- : float * int = 3.0, 2

Exemple 4 : avec déclaration locale# let f x = let y= exp x in (y+. 1.0/. y)/. 2. ;;f : float -> float = <fun># f 1.0 ;;- : float = 1.54308063482

Exemple 5 : déclaration simultanée# let ch x = let y= exp x in (y+. 1.0/. y)/. 2.

and sh x = let y= exp x in (y-. 1.0/. y)/. 2.;;ch : float -> float = <fun>sh : float -> float = <fun>

21/30

Notion de curryfication

Bijetion naturelleF(E1, E2) : applications de E1 dans E2 ;F(E × F , G) : applications de E × F dans G ;F(E ,F(F , G)) : applications de E dans F(F , G) ;

bijection naturelle !

ϕ : F(E × F , G) → F(E ,F(F , G))f 7−→ x 7→ (y 7→ f (x , y))

Forme curryfiée / non-curryfiéef ∈ F(E × F , G) : forme non curryfiée ;f ∈ F(E ,F(F , G)) : forme curryfiée ;intérêt des formes curryfiées : fonctions partielles !se généralise à F(E1 × · · · × En, G)

22/30

Notion de curryfication

Bijetion naturelleF(E1, E2) : applications de E1 dans E2 ;F(E × F , G) : applications de E × F dans G ;F(E ,F(F , G)) : applications de E dans F(F , G) ;bijection naturelle !

ϕ : F(E × F , G) → F(E ,F(F , G))f 7−→ x 7→ (y 7→ f (x , y))

Forme curryfiée / non-curryfiéef ∈ F(E × F , G) : forme non curryfiée ;f ∈ F(E ,F(F , G)) : forme curryfiée ;intérêt des formes curryfiées : fonctions partielles !se généralise à F(E1 × · · · × En, G)

22/30

Type et appels d’une fonction curryfiée

Typet_1 * t_2 -> t : non curryfiéet_1 -> (t_2 -> t) : curryfiéeCaml omet les parenthèses : t_1 -> t_2 -> t.

Appel d’une fonction curryfiéesi f : t1 -> t2 -> t et x de type t1, f x a le type t2 -> t ;si y de type t2, (f x) y a le type t ;parenthèses inutiles, priorité à la fonction : f x y

généralisation : f x1 x2 x3 ... xn

23/30

Type et appels d’une fonction curryfiée

Typet_1 * t_2 -> t : non curryfiéet_1 -> (t_2 -> t) : curryfiéeCaml omet les parenthèses : t_1 -> t_2 -> t.

Appel d’une fonction curryfiéesi f : t1 -> t2 -> t et x de type t1, f x a le type t2 -> t ;si y de type t2, (f x) y a le type t ;parenthèses inutiles, priorité à la fonction : f x y

généralisation : f x1 x2 x3 ... xn

23/30

Exemples Caml

Exemple 1 : max# max ;;- : 'a -> 'a -> 'a = <fun># max 20 ;;- : int -> int = <fun># max 20 58 ;;- : int = 58

Exemple 2 : make_vect# make_vect ;;- : int -> 'a -> 'a vect = <fun># make_vect 5 0 ;;- : int vect = [|0; 0; 0; 0; 0|]

Exemple 3 : sub_vect#sub_vect ;;- : 'a vect -> int -> int -> 'a vect = <fun>#sub_vect [| 1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0 |] 2 4 ;;- : float vect = [|3.0; 4.0; 5.0; 6.0|]

24/30

Exemples Caml

Exemple 1 : max# max ;;- : 'a -> 'a -> 'a = <fun># max 20 ;;- : int -> int = <fun># max 20 58 ;;- : int = 58

Exemple 2 : make_vect# make_vect ;;- : int -> 'a -> 'a vect = <fun># make_vect 5 0 ;;- : int vect = [|0; 0; 0; 0; 0|]

Exemple 3 : sub_vect#sub_vect ;;- : 'a vect -> int -> int -> 'a vect = <fun>#sub_vect [| 1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0 |] 2 4 ;;- : float vect = [|3.0; 4.0; 5.0; 6.0|]

24/30

Exemples Caml

Exemple 1 : max# max ;;- : 'a -> 'a -> 'a = <fun># max 20 ;;- : int -> int = <fun># max 20 58 ;;- : int = 58

Exemple 2 : make_vect# make_vect ;;- : int -> 'a -> 'a vect = <fun># make_vect 5 0 ;;- : int vect = [|0; 0; 0; 0; 0|]

Exemple 3 : sub_vect#sub_vect ;;- : 'a vect -> int -> int -> 'a vect = <fun>#sub_vect [| 1.0; 2.0; 3.0; 4.0; 5.0; 6.0; 7.0 |] 2 4 ;;- : float vect = [|3.0; 4.0; 5.0; 6.0|]

24/30

Création de fonctions curryfiées

Méthode 1 : function# function x -> (function y -> x+y) ;;- : int -> int -> int = <fun>

Méthode 2 : fun# fun x y -> x+y ;;- : int -> int -> int = <fun># (fun x y -> x+y) 1 6 ;;- : int = 7

Méthode 3 avec liaison# let somme x y = x+y ;;somme : int -> int -> int = <fun># somme 1 6 ;;- : int = 7

GénéralisationDéclaration + liaison : let f x1 x2 ... xn = expression

25/30

Création de fonctions curryfiées

Méthode 1 : function# function x -> (function y -> x+y) ;;- : int -> int -> int = <fun>

Méthode 2 : fun# fun x y -> x+y ;;- : int -> int -> int = <fun># (fun x y -> x+y) 1 6 ;;- : int = 7

Méthode 3 avec liaison# let somme x y = x+y ;;somme : int -> int -> int = <fun># somme 1 6 ;;- : int = 7

GénéralisationDéclaration + liaison : let f x1 x2 ... xn = expression

25/30

Création de fonctions curryfiées

Méthode 1 : function# function x -> (function y -> x+y) ;;- : int -> int -> int = <fun>

Méthode 2 : fun# fun x y -> x+y ;;- : int -> int -> int = <fun># (fun x y -> x+y) 1 6 ;;- : int = 7

Méthode 3 avec liaison# let somme x y = x+y ;;somme : int -> int -> int = <fun># somme 1 6 ;;- : int = 7

GénéralisationDéclaration + liaison : let f x1 x2 ... xn = expression

25/30

Création de fonctions curryfiées

Méthode 1 : function# function x -> (function y -> x+y) ;;- : int -> int -> int = <fun>

Méthode 2 : fun# fun x y -> x+y ;;- : int -> int -> int = <fun># (fun x y -> x+y) 1 6 ;;- : int = 7

Méthode 3 avec liaison# let somme x y = x+y ;;somme : int -> int -> int = <fun># somme 1 6 ;;- : int = 7

GénéralisationDéclaration + liaison : let f x1 x2 ... xn = expression

25/30

Expressions conditionnelles en Caml

if then elseif cond then a else b

cond expression booléenne ;a et b expressions de même typetype de l’expression = type commun à a et b.

Exemple# if true then 1 else 0 ;;- : int = 1# 1+(if true then 1 else 0) ;;- : int = 2# if true then 1.0 else 2 ;;Toplevel input:>if true then 1.0 else 2 ;;> ^This expression has type int,but is used with type float.

26/30

Expressions conditionnelles en Caml

Quelques subtilitéspas de else équivalent à else ()# if true then print_string "c'est vrai !" ;;c'est vrai !- : unit = ()

en Caml, séquence d’instructions séparées par des points-virgules ;une seule instruction dans les blocs if, else ou utilisation debegin ... end.# if true then x:=1 ; print_string "Exécuté ?" ;;Exécuté ?- : unit = ()# if false then x:=1 ; print_string "Exécuté ?" ;;Exécuté ?- : unit = ()# if false then begin x:=1 ; print_string "Exécuté ?" end ;;- : unit = ()

27/30

Expressions conditionnelles en Caml

Quelques subtilitéspas de else équivalent à else ()# if true then print_string "c'est vrai !" ;;c'est vrai !- : unit = ()

en Caml, séquence d’instructions séparées par des points-virgules ;une seule instruction dans les blocs if, else ou utilisation debegin ... end.# if true then x:=1 ; print_string "Exécuté ?" ;;Exécuté ?- : unit = ()# if false then x:=1 ; print_string "Exécuté ?" ;;Exécuté ?- : unit = ()# if false then begin x:=1 ; print_string "Exécuté ?" end ;;- : unit = ()

27/30

Boucles

boucle forfor i = i1 to i2 do instructions done.i prend les valeurs de i1 à i2 (inclus) ;si i2 < i1 pas d’exécution ;corps de boucle : instructions, séparées par des point-virgules, detype unit

type de la boucle : unit.pas de modification du compteur de boucle !variante : for i = i1 downto i2 do instructions done

28/30

Boucles

Exemple de boucle for : factoriellelet fact n=

let y=ref 1 infor i=1 to n do

y:= !y * idone ;!y

;;

29/30

Boucles

boucle whilesimilaire : while cond do instructions done

mêmes restrictions

Exemple de boucle while : Euclidelet pgcd a b=

let x=ref a and y=ref b inwhile !y > 0 do

let r= !x mod !y inx:= !y ;y:= r

done ;!x ;;

30/30