Programmation Fonctionnelle
Stefano Guerrini
stefano.guerrini@univ-paris13.fr
http://www.lipn.univ-paris13.fr/~guerrini
LIPN - Institut Galil´ee, Universit´e Paris Nord 13
Licence Info 3
evrier 2013
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 1 / 131
Gestion de la m´emoire
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 68 / 131
Gestion de la m´emoire emoire de programme
Des zones di´erents de m´emoire
M´emoire statique
Iallou´ee au moment du chargement du programme (e.g., au d´emarrage de la
boucle interactive).
Ine change pas de dimension, mais sont contenu peut se modifier au long de
l’ex´ecution.
Icontient des donn´ees (ou du code) n´ecessaires tout au long de l’ex´ecution du
programme (e.g., le code et les donn´ees de la boucle interactive).
M´emoire dynamique : le tas (en anglais, heap)
IDes structures (e.g., des listes) sont ajout´ees ou supprim´ees dynamiquement.
Pile d’ex´ecution (en anglais : stack)
IComme dans le tas, des donn´ees sont ajout´ees et supprim´ees dynamiquement.
IMais, dans la pile, les donn´ees sont supprim´ees en respectant l’ordre inverse
d’allocation (DEPS)
ILa pile est organis´ee en cadres de piles (en anglais, stack frames)qui
contiennent les donn´ees des appels de fonctions.
ILa pile contient aussi des valeurs interm´ediaire n´ecessaires seulement pendant
l’´evaluation di une expression de la fonction.
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 69 / 131
Gestion de la m´emoire emoire de programme
Garbage collection
En OCaml on n’a pas des commandes explicites d’allocation ou de-allocation
de la m´emoire.
Le structures sont allou´e au moyen des constructeur du type de donn´ees
(e.g., pour les liste le cons ::).
Quand une structure (par exemple une liste) n’est plus accessible alors son
espace m´emoire peut ˆetre r´eutilis´e.
C’est la tˆache du Garbage Collector (GC, parfois Ramassage de miettes), qui
est lanc´e quand le syst`eme OCaml a besoin de m´emoire.
Comme en Java.
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 70 / 131
Gestion de la m´emoire emoire de programme
La pile
A chaque appel de fonction, OCaml alloue un cadre sur la pile.
Chaque cadre de pile stockes (parmi d’autres)
Iles valeurs locales et les param`etres d’un appel de fonction
Iles informations n´ecessaires pour revenir au point de l’appel de la fonction
Quand cet appel de fonction est termin´e, sa m´emoire locale est balay´ee du
sommet de la pile.
Dans l’´evaluation d’une fonction r´ecursive on a un cadre de pile pour chaque
appel r´ecursif.
IPourtant, si on fait une r´ecursion trop profonde on risque d’´epuiser l’espace
disponible pour la pile.
IMais attention, le risque est r´eel seulement si ont fait au moins des dizaines ou
centaines de milliers d’appels r´ecursives.
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 71 / 131
Gestion de la m´emoire emoire de programme
Appel terminal
Une fonction fapp`ele une fonction get le r´esultat de l’´evaluation de gest
envoy´e tout de suite par f.
Iexemple d’appel terminal :
let f x = if x = 0 then 0 else g x
Iexemple d’appel non-terminal :
letfx=x+gx
Dans le cas d’appel terminal, on n’a plus besoin des valeurs locales de la
fonction fquand on ´evalue g.
Le cadre de fsur la pile peut ˆetre lib´er´e avant d’´evaluer g.
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 72 / 131
Gestion de la m´emoire emoire de programme
R´ecursion terminale
En anglais, tail recursion.
C’est une fonction r´ecursive, avec tous les appels r´ecursifs `a des positions
terminales.
let rec fold_left f b = function
|[]->b
| h::r -> fold_left f (f b h) r;;
Peut importe la profondeur de r´ecurrence, l’utilisation d’espace reste
constante :
La fonction r´ecursive est ex´ecut´ee comme une boucle d’it´eration !
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 73 / 131
Gestion de la m´emoire emoire de programme
R´e´ecrire une fonction en r´ecursion terminale
Il est parfois possible de r´ecrire une fonction r´ecursive en une fonction
r´ecursive terminale ´equivalente.
let rec somme = function
|[]->0
| hd :: tl -> hd + somme tl;;
let somme ls =
let rec somme_term acc = function
|[]->acc
| hd :: tl -> somme_term (hd + acc) tl
in somme_term 0 ls;;
Normalement, il faut ajouter des param`etres `a la fonction.
IUne fonction r´ecursive terminale correspond `a une version it´erative de la
fonction.
ILes param`etres additionnels sont les donn´ees (l’´etat) modifi´ees `a chaque
it´eration.
let fibonacci n =
let rec fib n =
if (n = 0) then (1,0)
else let (a,b) = fib (n-1)
in (a+b, a)
in fst (fib n);;
let fibonacci n =
let rec fib (a,b) n =
if (n = 0) then (a,b)
else fib (a+b, a) (n-1)
in fst (fib (1, 0) n);;
La r´ecursion terminale permet d’´eviter des d´epassements de pile (en anglais,
stack overflow).
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 74 / 131
Gestion de la m´emoire emoire de programme
R´ecursion terminale et fonctions fold
La fonction fold left est r´ecursive terminale :
let rec fold_left f b = function
|[]->b
| h::r -> fold_left f (f b h) r;;
La fonction fold right n’est pas r´ecursive terminale :
let rec fold_right f l b = match l with
|[]->b
| h::r -> f h (fold_right f r b);;
S. Guerrini (LIPN - Paris 13) Programmation Fonctionnelle evrier 2013 75 / 131
1 / 3 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !