Coderstand

PF: Les fonctions en tant que paramètres

tags: programmation fonctionnelle

21/08/2017 (c'était un lundi)

Rappel du sommaire

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 dans variable a, mais on fait ça juste pour pouvoir les passer à la fonction ajoute1. 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écute fonction1, 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.


Brice Coquereau

Bonjour! Je suis Brice Coquereau, parisien, développeur, flexitarien, et amateur de chats. Je vais à des meetups assez souvent. Venez me parler sur Mastodon ou Twitter (mais Mastodon c'est mieux)

TwitterFacebookLinkedin