Fonctions d’ordre supérieur Programmation Fonctionnelle Master 2 I2L apprentissage Sébastien Verel [email protected] http://www-lisic.univ-littoral.fr/~verel Université du Littoral Côte d’Opale Laboratoire LISIC Equipe OSMOSE Septembre 2016 Langage à base de fonctions Fonction d’ordre supérieur Plan 1 Langage à base de fonctions 2 Fonction d’ordre supérieur 3 Fonction anonyme Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Paradigme fonctionnel Réfuter la notion d’instruction, Pas de notion de temps, Pas de modification (comme en mathématique) Principe Eléments de base = fonctions cf. lambda calcul Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Paradigme fonctionnel Différent impératif / fonctionnel Impératif : Fonctionnel : {I1 ; I2 } f1 o f2 Approximativement Programmation impérative : Exécuter un programme : évaluer un arbre, dont la valeur n’est pas importante. Au fur et à mesure de l’évaluation de l’arbre, des actions sont produites sur le monde extérieur. Sens au programme = actions Programmation fonctionnelle : Exécuter un programme : évaluer un arbre, et le résultat du programme est la valeur de l’arbre. Sens au programme = valeur Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Paradigme fonctionnel S’appuie sur des mécanismes mentaux primitifs : Définition par récurrence Pas d’effet de bord, pas d’opérations d’affectation : En interne, pile pour stocker les informations temporaires (notion d’environnement) Calcul consiste en l’évaluation d’une fonction pour éviter toute modification ”d’états” Résultat dépend seulement des entrées et non pas de l’état du programme Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Paradigme fonctionnel S’appuie sur des mécanismes mentaux primitifs : Définition par récurrence Pas d’effet de bord, pas d’opérations d’affectation : En interne, pile pour stocker les informations temporaires (notion d’environnement) Calcul consiste en l’évaluation d’une fonction pour éviter toute modification ”d’états” Résultat dépend seulement des entrées et non pas de l’état du programme transparence référentielle : remplacement des entrées par des fonctions qui ont les mêmes valeurs Auto-référent : capable de parler de lui-même Fonction, type de base Construction au cours de l’exécution Langage à base de fonctions Fonction d’ordre supérieur Transparence référentielle Remplacement des entrées par des fonctions qui ont les mêmes valeurs A tester (module ex04) ajout(X, Y) -> X + Y. one() -> 1. two() -> 2. ex04:ajout(1, 2). ex04:ajout(ex04:one(), ex04:two()). Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur 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). Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur 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 Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme 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. Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme 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éciser que one et two sont bien des fonctions. Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Fonction d’ordre supérieur Fonction d’ordre 1 Définie à partir de fonctions d’ordre zéro. Remarque : les fonctions d’ordre zéro sont les fonctions de base de Erlang. Fonction d’ordre n + 1 Définie à partir de fonctions d’ordre n. Langage à base de fonctions Fonction d’ordre supérieur Fonction d’ordre supérieur Synthaxe functionName(f1, f2, ...) -> f1(...) ... Appel de fonction avec fonctions en paramètres functionName(fun f1/arity1, fun f2/arity2, ...). Exemple ajoutF(X, Y) -> X() + Y(). ex04:ajoutF(fun ex04:one/0, fun ex04:two/0). 3 Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Petits exos express Définir une fonction qui ajoute 1 à tous les nombres d’une liste d’entier Définir une fonction qui soustrait 1 à tous les nombres d’une liste d’entier Définir une fonction qui inverse toutes les listes d’une liste de listes. (Utiliser lists:reverse/1) Langage à base de fonctions Fonction d’ordre supérieur Un peu de recul Comment généraliser toutes ces fonctions qui répondent à la même structure ? Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Fonction map map(_, []) -> []; map(F, [ Head | Tail ]) -> [ F(Head) | map(F, Tail) ]. F est un paramètre de type fun Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Fonction map map(_, []) -> []; map(F, [ Head | Tail ]) -> [ F(Head) | map(F, Tail) ]. F est un paramètre de type fun incr(X) X + decr(X) X - -> 1. -> 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). Langage à base de fonctions Fonction d’ordre supérieur 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 Langage à base de fonctions Fonction anonyme les fun Définition Fonction sans nom Synthaxe fun(Args1) -> Expression1 ; (Args2) -> Expression2 ; ... (Args3) -> Expression3 end Fonction d’ordre supérieur Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur 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). Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Metaprogrammation Possibilité qu’a une fonction de déterminer à l’exécution quelle autre fonction appliquée Possibilité d’écrire des programmes qui crée d’autres programmes. Apply apply(fonction, [ Args ]) ou apply(module, fonction, [ Args ]) Langage à base de fonctions Fonction d’ordre supérieur Exemple Exemple Plus1 = fun(X) -> X + 1 end. Plus = fun(X, Y) -> X + Y end. apply(Plus1, [ 2 ]). apply(Plus, [ 3, 4 ]). Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Fonction comme résultat Il est possible que le résultat d’une fonction soit une fonction Exemple addOne() -> fun(X) -> X + 1 end. Langage à base de fonctions Fonction comme résultat Exemple ex04:addOne(3). Fonction d’ordre supérieur Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Fonction comme résultat Exemple ex04:addOne(3). ** exception error: undefined function ex04:addOne/1 Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Fonction comme résultat Exemple ex04:addOne(3). ** exception error: undefined function ex04:addOne/1 MyF = ex04:addOne(). MyF(3). ex04:addOne()(3). Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Fonction comme résultat Exemple ex04:addOne(3). ** exception error: undefined function ex04:addOne/1 MyF = ex04:addOne(). MyF(3). ex04:addOne()(3). * 1: syntax error before: ’(’ Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Fonction comme résultat 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). Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Fonction comme résultat 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 ]). Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Fermeture Notion importante ! Une fermeture est une fonction avec son environnement d’exécution fermeture environnement < A=1, stop, split=fun... > f=fun... fonction Langage à base de fonctions Fonction d’ordre supérieur 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). Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Fermetures Exemple add(A) -> fun(X) -> X + A end. addB() -> B = 1, fun(X) -> X + B end. (ex04:addB())(3). Les variables A dans add et B dans addB appartiennent à l’environnement de chaque fonction résultat que l’on appelle des fermetures. Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme 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ée et inutilisée. Langage à base de fonctions Fonction d’ordre supérieur Fermetures, variables locales (2) Exemple cacheC(A) -> B = 1, F = fun() -> C = B + A end, F(), C. Impossible la variable C n’existe qu’à l’intérieure de la fonction F. Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Les funs récursives ! Problème les fun n’ont pas de nom pour être récursivement appelée... La solution consiste à mettre la fun en argument : Exemple longueur d’une liste Long = fun([], _) -> 0; ([_|T], Fun) -> 1 + Fun(T, Fun) end. Long([1, 2, 3], Long). Fonction anonyme Langage à base de fonctions Fonction d’ordre supérieur Fonction anonyme Petits exos Exercice 1 : Fonction dérivée Ecrire une fonction calculant une fonction qui approxime la fonction dérivée. On rappelle que (f (x + h) − f (x))/h est une valeur approchée de la fonction dérivée de f en x lorsque h est petit. Exercice 2 : Les funs en récursivité terminale Ecrire une fonction terminale enveloppée (qui contient une fonction anonyme récursive terminale) pour calculer la longueur d’une liste. Exercice 3 : Fonction puissance Ecrire une fonction qui calcule, pour n entier positif, la fonction puissance qui à x associe x n .