PF: Les fonctions en tant que paramètres
tags: programmation fonctionnelle
21/08/2017 (c'était un lundi)
Rappel du sommaire
- Les fonctions en tant que paramètres <--- vous êtes ici
- L’immutabilité
- Les fonctions pures
- L’application partielle
Passer des fonctions à des fonctions? Mais pour quelle fonction?
Un des principes structurants de la programmation fonctionnelle est de passer des fonctions en tant que paramètres à d’autres fonctions, et de pouvoir renvoyer une fonction en tant que retour d’une autre fonction. A première vue, cela peut sembler rajouter une dose de complexité pour peu de gain.
Par exemple, en partant d’une fonction qui renvoie une valeur (avec ou sans calcul, cela importe peu)
const fonction1 = () => {
// Calcul très compliqué
return 1;
}
Exemple 1: Sans passer de fonctions en paramètre, on a le code suivant
const ajoute1 = (param) => {
return param + 1;
}
let a = fonction1();
let b = ajoute1(a);
// Ou
let b = ajoute1(fonction1());
Exemple 1bis: En passant une fonction, on a
const ajoute1bis = (fonction) => {
return fonction() + 1;
}
// Plus besoin de variable a
let b = ajoute1bis(fonction1);
A première vue, c’est très similaire.
Mais si on prend un peu de recul, il y a 2 gains à la seconde écriture :
- (Avec la déclaration de
variable a
) On ne fait plus déborder les informations de retour de fonction1 à un endroit où elles n’ont aucun intérêt. Dans l’exemple 1, on récupère les informations dansvariable a
, mais on fait ça juste pour pouvoir les passer à la fonctionajoute1
. Si notre code continue plus loin, on va garder une variable dont on a aucune utilité. - Sans la déclaration de
variable a
, la principale différence est dans l’exécution. L’exemple 1 exécutefonction1
, puis passe le résultat àajoute1
. Si on prend un cas un peu plus complexe suivant
const fonction2 = () => {
// Calcul très compliqué 2
return 2;
}
const ajoutePeutEtre = (number, shouldAdd) => {
if(shouldAdd) {
return number + 1;
} else {
return 0;
}
}
let a = fonction2();
let b = ajoutePeutEtre(a, false);
(On imagine bien que false n’est pas écrit dans le code en dur, mais qu’il est le résultat d’une autre fonction, qui peut renvoyer true ou false)
On se rend compte que fonction2
fait son calcul compliqué, mais que le résultat n’est pas utilisé au final.
En passant la fonction2 en paramètre, on aurait eu
const ajoutePeutEtreBis = (fonction, shouldAdd) => {
if(shouldAdd) {
return fonction() + 1;
} else {
return 0;
}
}
let b = ajoutePeutEtreBis(fonction2, false);
Et là, fonction2 n’aurait même pas été appelée, parce qu’on ne rentre pas dans cette branche du code. Donc on gagne en performance.
Conclusion
En programmation fonctionnelle, les fonctions sont des variables comme les autres, et peuvent être passées en paramètres d’autres fonctions, ou même renvoyées comme retour de fonctions (on le verra bien plus en détail dans l’article sur l’application partielle).
Cela permet un gain de performances, car la fonction n’est réellement appelée que lorsqu’on en a besoin. On obtient aussi une plus grande souplesse, car on est plus obligé d’appeler récupérer des valeurs avant de les utiliser, donc un potentiel gain de performance.
A la fin de cet article, on a l’impression que c’est quand même beaucoup de complications pour peu de gains, mais cet article servait surtout à poser les bases, nous verrons plus tard d’autres avantages qui n’auraient pas été possibles sans passer des fonctions en tant que paramètres.