Programmation Fonctionnelle Master 2 I2L apprentissage
S´ebastien Verel verel@lisic.univ-littoral.fr
http://www-lisic.univ-littoral.fr/~verel
Universit´e du Littoral Cˆote d’Opale Laboratoire LISIC Equipe OSMOSE
Septembre 2016
Plan
1 Langage `a base de fonctions
2 Fonction d’ordre sup´erieur
3 Fonction anonyme
Paradigme fonctionnel
R´efuter la notion d’instruction, Pas de notion de temps,
Pas de modification (comme en math´ematique)
Principe
El´ements de base = fonctions cf. lambda calcul
Paradigme fonctionnel
Diff´erent imp´eratif / fonctionnel Imp´eratif : {I1 ; I2} Fonctionnel : f1 o f2
Approximativement
Programmation imp´erative :
Ex´ecuter un programme : ´evaluer un arbre, dont la valeur n’est pas importante.
Au fur et `a mesure de l’´evaluation de l’arbre, des actions sont produites sur le monde ext´erieur.
Sens au programme = actions Programmation fonctionnelle :
Ex´ecuter un programme : ´evaluer un arbre,
et le r´esultat du programme est la valeur de l’arbre.
Sens au programme = valeur
Langage `a base de fonctions Fonction d’ordre sup´erieur Fonction anonyme
Paradigme fonctionnel
S’appuie sur des m´ecanismes mentaux primitifs : D´efinition par r´ecurrence
Pas d’effet de bord, pas d’op´erations d’affectation :
En interne, pile pour stocker les informations temporaires (notion d’environnement)
Calcul consiste en l’´evaluation d’une fonction pour ´eviter toute modification ”d’´etats”
R´esultat d´epend seulement des entr´ees et non pas de l’´etat du programme
des fonctions qui ont les mˆemes valeurs
Auto-r´ef´erent: capable de parler de lui-mˆeme Fonction, type de base
Construction au cours de l’ex´ecution
Paradigme fonctionnel
S’appuie sur des m´ecanismes mentaux primitifs : D´efinition par r´ecurrence
Pas d’effet de bord, pas d’op´erations d’affectation :
En interne, pile pour stocker les informations temporaires (notion d’environnement)
Calcul consiste en l’´evaluation d’une fonction pour ´eviter toute modification ”d’´etats”
R´esultat d´epend seulement des entr´ees et non pas de l’´etat du programme
transparence r´ef´erentielle: remplacement des entr´ees par des fonctions qui ont les mˆemes valeurs
Auto-r´ef´erent: capable de parler de lui-mˆeme Fonction, type de base
Construction au cours de l’ex´ecution
Transparence r´ ef´ erentielle
Remplacement des entr´ees par des fonctions qui ont les mˆemes valeurs
A tester (module ex04) ajout(X, Y) ->
X + Y.
one() -> 1.
two() -> 2.
ex04:ajout(1, 2).
ex04:ajout(ex04:one(), ex04:two()).
Fonctions, types de base
A tester (module ex04) ajoutF(X, Y) ->
X() + Y().
ex04:ajoutF(1, 2).
ex04:ajoutF(one, two).
ex04:ajoutF(ex04:one, ex04:two).
Fonctions, types de base
A tester (module ex04) ajoutF(X, Y) ->
X() + Y().
ex04:ajoutF(1, 2).
ex04:ajoutF(one, two).
ex04:ajoutF(ex04:one, ex04:two).
ex04:ajoutF(1, 2).
** exception error: bad function 1 Normal 1 et 2 ne sont pas des fonctions
Fonctions, types de base
A tester (module ex04) ajoutF(X, Y) ->
X() + Y().
ex04:ajoutF(1, 2).
ex04:ajoutF(one, two).
ex04:ajoutF(ex04:one, ex04:two).
ex04:ajoutF(one, two).
** exception error: bad function 1
Normal one et two ne sont pas des fonctions mais des atomes.
Fonctions, types de base
A tester (module ex04) ajoutF(X, Y) ->
X() + Y().
ex04:ajoutF(1, 2).
ex04:ajoutF(one, two).
ex04:ajoutF(ex04:one, ex04:two).
ex04:ajoutF(ex04:one, ex04:two).
* 1: illegal expression
Normal il faut pr´eciser que one et two sont bien des fonctions.
Fonction d’ordre sup´ erieur
Fonction d’ordre 1
D´efinie `a partir de fonctions d’ordre z´ero.
Remarque : les fonctions d’ordre z´ero sont les fonctions de base de Erlang.
Fonction d’ordren+ 1
D´efinie `a partir de fonctions d’ordren.
Fonction d’ordre sup´ erieur
Synthaxe
functionName(f1, f2, ...) ->
f1(...) ...
Appel de fonction avec fonctions en param`etres
functionName(fun f1/arity1, fun f2/arity2, ...).
Exemple
ajoutF(X, Y) ->
X() + Y().
ex04:ajoutF(fun ex04:one/0, fun ex04:two/0).
3
Petits exos express
D´efinir une fonction qui ajoute 1 `a tous les nombres d’une liste d’entier
D´efinir une fonction qui soustrait 1 `a tous les nombres d’une liste d’entier
D´efinir une fonction qui inverse toutes les listes d’une liste de listes. (Utiliser lists:reverse/1)
Un peu de recul
Comment g´en´eraliser toutes ces fonctions qui r´epondent `a la mˆeme structure ?
Langage `a base de fonctions Fonction d’ordre sup´erieur Fonction anonyme
Fonction map
map(_, []) ->
[];
map(F, [ Head | Tail ]) ->
[ F(Head) | map(F, Tail) ].
Fest un param`etre de typefun
X + 1. decr(X) -> X - 1.
L = lists:seq(1, 6).
ex04:map(fun ex04:incr/1, L). ex04:map(fun ex04:decr/1, L).
LL = [lists:seq(1,3), lists:seq(1,4), lists:seq(1,6)]. ex04:map(fun lists:reverse/1, LL).
Fonction map
map(_, []) ->
[];
map(F, [ Head | Tail ]) ->
[ F(Head) | map(F, Tail) ].
Fest un param`etre de typefun incr(X) ->
X + 1.
decr(X) ->
X - 1.
L = lists:seq(1, 6).
ex04:map(fun ex04:incr/1, L).
ex04:map(fun ex04:decr/1, L).
LL = [lists:seq(1,3), lists:seq(1,4), lists:seq(1,6)].
ex04:map(fun lists:reverse/1, LL).
Application partielle de fonction
Exemple
increment(L) ->
map(fun incr/1, L).
decrement(L) ->
map(fun decr/1, L).
ex04:increment(L).
ex04:decrement(L).
Fonction anonyme
lesfun
D´efinition
Fonction sans nom
Synthaxe fun(Args1) ->
Expression1 ; (Args2) ->
Expression2 ; ...
(Args3) ->
Expression3 end
Exemple
fun(X) ->
X + 1 end
Que l’on peut utiliser avec map :
ex04:map(fun(X) -> X + 1 end, L).
ex04:map(fun(X) -> X - 1 end, L).
Metaprogrammation
Possibilit´e qu’a une fonction de d´eterminer `a l’ex´ecution quelle autre fonction appliqu´ee
Possibilit´e d’´ecrire des programmes qui cr´ee d’autres programmes.
Apply
apply(fonction, [ Args ]) ou
apply(module, fonction, [ Args ])
Exemple
Exemple
Plus1 = fun(X) -> X + 1 end.
Plus = fun(X, Y) -> X + Y end.
apply(Plus1, [ 2 ]).
apply(Plus, [ 3, 4 ]).
Fonction comme r´ esultat
Il est possible que le r´esultat d’une fonction soit une fonction
Exemple addOne() ->
fun(X) ->
X + 1 end.
Langage `a base de fonctions Fonction d’ordre sup´erieur Fonction anonyme
Fonction comme r´ esultat
Exemple
ex04:addOne(3).
MyF = ex04:addOne(). MyF(3).
ex04:addOne()(3).
* 1: syntax error before: ’(’ (ex04:addOne())(3).
apply(ex04:addOne(), [ 3 ]).
Langage `a base de fonctions Fonction d’ordre sup´erieur Fonction anonyme
Fonction comme r´ esultat
Exemple
ex04:addOne(3).
** exception error: undefined function ex04:addOne/1
MyF(3).
ex04:addOne()(3).
* 1: syntax error before: ’(’ (ex04:addOne())(3).
apply(ex04:addOne(), [ 3 ]).
Langage `a base de fonctions Fonction d’ordre sup´erieur Fonction anonyme
Fonction comme r´ esultat
Exemple
ex04:addOne(3).
** exception error: undefined function ex04:addOne/1 MyF = ex04:addOne().
MyF(3).
ex04:addOne()(3).
(ex04:addOne())(3).
apply(ex04:addOne(), [ 3 ]).
Langage `a base de fonctions Fonction d’ordre sup´erieur Fonction anonyme
Fonction comme r´ esultat
Exemple
ex04:addOne(3).
** exception error: undefined function ex04:addOne/1 MyF = ex04:addOne().
MyF(3).
ex04:addOne()(3).
* 1: syntax error before: ’(’
apply(ex04:addOne(), [ 3 ]).
Langage `a base de fonctions Fonction d’ordre sup´erieur Fonction anonyme
Fonction comme r´ esultat
Exemple
ex04:addOne(3).
** exception error: undefined function ex04:addOne/1 MyF = ex04:addOne().
MyF(3).
ex04:addOne()(3).
* 1: syntax error before: ’(’
(ex04:addOne())(3).
Fonction comme r´ esultat
Exemple
ex04:addOne(3).
** exception error: undefined function ex04:addOne/1 MyF = ex04:addOne().
MyF(3).
ex04:addOne()(3).
* 1: syntax error before: ’(’
(ex04:addOne())(3).
apply(ex04:addOne(), [ 3 ]).
Fermeture
Notion importante !
Une fermeture est une fonction avec son environnement d’ex´ecution
< A=1, stop, split=fun... >
f=fun...
environnement
fonction
fermeture
Fermeture
Exemples add(A) ->
fun(X) ->
X + A end.
Add3 = ex04:add(3).
Add1 = ex04:add(1).
Add3(4).
Add1(4).
ex04:map(ex04:add(1), L).
ex04:map(ex04:add(-1), L).
Fermetures
Exemple add(A) ->
fun(X) ->
X + A end.
addB() ->
B = 1, fun(X) ->
X + B end.
(ex04:addB())(3).
Les variables A dansaddet B dans addBappartiennent `a l’environnement de chaque fonction r´esultat que l’on appelle des fermetures.
Fermetures, variables locales (1)
Exemple cacheX(A) ->
X = 1,
F = fun(X) ->
X + A end, F(2).
Le compilateur vous signale que la variable X est effectivement cach´ee et inutilis´ee.
Fermetures, variables locales (2)
Exemple cacheC(A) ->
B = 1, F = fun() ->
C = B + A end,
F(), C.
Impossible la variable C n’existe qu’`a l’int´erieure de la fonction F.
Les funs r´ ecursives !
Probl`eme les funn’ont pas de nom pour ˆetre r´ecursivement appel´ee...
La solution consiste `a mettre lafun en argument : Exemple longueur d’une liste
Long =
fun([], _) ->
0;
([_|T], Fun) ->
1 + Fun(T, Fun) end.
Long([1, 2, 3], Long).
Petits exos
Exercice 1 : Fonction d´eriv´ee
Ecrire une fonction calculant une fonction qui approxime la fonction d´eriv´ee.
On rappelle que (f(x+h)−f(x))/h est une valeur approch´ee de la fonction d´eriv´ee de f enx lorsqueh est petit.
Exercice 2 : Les funs en r´ecursivit´e terminale
Ecrire une fonction terminale envelopp´ee (qui contient une fonction anonyme r´ecursive terminale) pour calculer la longueur d’une liste.
Exercice 3 : Fonction puissance
Ecrire une fonction qui calcule, pourn entier positif, la fonction puissance qui `a x associexn.