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
Top Related