Qu’est-Ce qu’une Fonction Pure ?
Avantages
Il y a plusieurs avantages à utiliser des fonctions pures, à la fois en termes de performances et de convivialité.
Lisibilité
Les fonctions pures sont beaucoup plus faciles à lire et à raisonner. Toutes les entrées et dépendances pertinentes sont fournies en tant que paramètres, de sorte qu’aucun effet n’est observé qui modifie les variables en dehors de l’ensemble des entrées.
Cela signifie que nous pouvons comprendre rapidement une fonction et ses dépendances, simplement en lisant la déclaration de la fonction. Ainsi, si une fonction est déclarée comme f(a, b, c)
alors nous savons que seuls a
b
, et c
sont des dépendances de f
.
Portabilité
Comme toutes les dépendances sont fournies en tant que paramètres d’entrée et ne sont pas accessibles via un contexte global, ces dépendances peuvent être échangées en fonction du contexte dans lequel la fonction est appelée.
Cela signifie qu’une même fonction peut agir sur différentes implémentations d’une même ressource, par exemple.
Cela rend le code beaucoup plus portable et réutilisable car la même fonction peut être utilisée dans divers contextes, plutôt que d’avoir à écrire une fonction différente simplement pour utiliser une implémentation différente de la même classe.
Par exemple, au lieu d’avoir à écrire deux fonctions impures différentes pour utiliser deux enregistreurs différents qui sont stockés globalement, une fonction pure prendrait simplement l’enregistreur souhaité en entrée.
Test
L’absence d’effets secondaires rend les fonctions pures très faciles à tester, car il suffit de tester que les entrées produisent les sorties souhaitées. Nous n’avons pas besoin de vérifier la validité d’un état de programme global dans nos tests de fonctions spécifiques.
De plus, comme toutes les dépendances sont fournies en entrée, nous pouvons facilement nous moquer des dépendances. Dans un cadre impur, nous devrions suivre l’état d’une dépendance globale tout au long de tous les tests.
Cependant, dans un paramètre pur, nous fournirions simplement toutes les dépendances en entrée. Nous n’avons plus à nous soucier de maintenir l’état global tout au long de nos tests, et nous pouvons désormais potentiellement fournir différentes versions de dépendances à différents tests.
Cela nous permet de tester des fonctions tout en ayant explicitement le contrôle des dépendances fournies dans chaque test.
Transparence référentielle
La transparence référentielle fait référence à la possibilité de remplacer l’appel d’une fonction par sa valeur de sortie correspondante sans modifier le comportement d’un programme.
Pour obtenir une transparence référentielle, une fonction doit être pure. Cela présente des avantages en termes de lisibilité et de rapidité. Les compilateurs sont souvent capables d’optimiser le code qui présente une transparence référentielle.
Mise en cache
Comme les fonctions pures renvoient toujours la même sortie pour la même entrée, nous pouvons mettre en cache les résultats des appels de fonctions pures.
La mise en cache fait référence à l’utilisation d’une technique, telle que la mémorisation, pour stocker les résultats des fonctions afin que nous n’ayons besoin de les calculer qu’une seule fois.
Typiquement, pour une fonction f: Input -> Output
ceci est accompli via une carte (telle qu’une carte de hachage) de Input -> Output
.
Lors de l’exécution d’une fonction, nous vérifions d’abord si la carte contient l’entrée en tant que clé. Si c’est le cas, nous renvoyons la valeur de sortie de la carte, sinon, nous calculons f(input)
, puis stockons la sortie dans la carte avant de la renvoyer.